X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FJalview2XML.java;h=4a1502483361672238d09bd8d2a0354b5f8ef154;hb=9e926ac4305fd9dff38b6e079e55b4f50664d544;hp=24b6e7801f375c9d63fbf0bdf47d37f2084a0c80;hpb=ecb334f98fca8ed9f27b6a7d027dea3bd4213023;p=jalview.git diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index 24b6e78..4a15024 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -20,6 +20,8 @@ */ package jalview.gui; +import jalview.analysis.Conservation; +import jalview.api.FeatureColourI; import jalview.api.ViewStyleI; import jalview.api.structures.JalviewStructureDisplayI; import jalview.bin.Cache; @@ -27,14 +29,19 @@ import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; +import jalview.datamodel.GraphLine; import jalview.datamodel.PDBEntry; import jalview.datamodel.RnaViewerModel; +import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.datamodel.StructureViewerModel; import jalview.datamodel.StructureViewerModel.StructureData; import jalview.ext.varna.RnaModel; import jalview.gui.StructureViewer.ViewerType; +import jalview.io.DataSourceType; +import jalview.io.FileFormat; +import jalview.renderer.ResidueShaderI; import jalview.schemabinding.version2.AlcodMap; import jalview.schemabinding.version2.AlcodonFrame; import jalview.schemabinding.version2.Annotation; @@ -71,16 +78,17 @@ import jalview.schemabinding.version2.Viewport; import jalview.schemes.AnnotationColourGradient; import jalview.schemes.ColourSchemeI; import jalview.schemes.ColourSchemeProperty; -import jalview.schemes.GraduatedColor; -import jalview.schemes.ResidueColourScheme; +import jalview.schemes.FeatureColour; import jalview.schemes.ResidueProperties; import jalview.schemes.UserColourScheme; import jalview.structure.StructureSelectionManager; import jalview.structures.models.AAStructureBindingModel; import jalview.util.MessageManager; import jalview.util.Platform; +import jalview.util.StringUtils; import jalview.util.jarInputStreamProvider; import jalview.viewmodel.AlignmentViewport; +import jalview.viewmodel.ViewportRanges; import jalview.viewmodel.seqfeatures.FeatureRendererSettings; import jalview.viewmodel.seqfeatures.FeaturesDisplayed; import jalview.ws.jws2.Jws2Discoverer; @@ -106,6 +114,7 @@ import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; @@ -117,14 +126,12 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.StringTokenizer; import java.util.Vector; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; import javax.swing.JInternalFrame; -import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.exolab.castor.xml.Marshaller; @@ -164,7 +171,9 @@ public class Jalview2XML */ Map seqRefIds = null; - Vector frefedSequence = null; + Map incompleteSeqs = null; + + List frefedSequence = null; boolean raiseGUI = true; // whether errors are raised in dialog boxes or not @@ -172,13 +181,13 @@ public class Jalview2XML * Map of reconstructed AlignFrame objects that appear to have come from * SplitFrame objects (have a dna/protein complement view). */ - private Map splitFrameCandidates = new HashMap(); + private Map splitFrameCandidates = new HashMap<>(); /* * Map from displayed rna structure models to their saved session state jar * entry names */ - private Map rnaSessions = new HashMap(); + private Map rnaSessions = new HashMap<>(); /** * create/return unique hash string for sq @@ -207,39 +216,23 @@ public class Jalview2XML } } - void clearSeqRefs() + void initSeqRefs() { - if (_cleartables) + if (seqsToIds == null) { - if (seqRefIds != null) - { - seqRefIds.clear(); - } - if (seqsToIds != null) - { - seqsToIds.clear(); - } - // seqRefIds = null; - // seqsToIds = null; + seqsToIds = new IdentityHashMap<>(); } - else + if (seqRefIds == null) { - // do nothing - warn("clearSeqRefs called when _cleartables was not set. Doing nothing."); - // seqRefIds = new Hashtable(); - // seqsToIds = new IdentityHashMap(); + seqRefIds = new HashMap<>(); } - } - - void initSeqRefs() - { - if (seqsToIds == null) + if (incompleteSeqs == null) { - seqsToIds = new IdentityHashMap(); + incompleteSeqs = new HashMap<>(); } - if (seqRefIds == null) + if (frefedSequence == null) { - seqRefIds = new HashMap(); + frefedSequence = new ArrayList<>(); } } @@ -252,78 +245,186 @@ public class Jalview2XML this.raiseGUI = raiseGUI; } + /** + * base class for resolving forward references to sequences by their ID + * + * @author jprocter + * + */ + abstract class SeqFref + { + String sref; + + String type; + + public SeqFref(String _sref, String type) + { + sref = _sref; + this.type = type; + } + + public String getSref() + { + return sref; + } + + public SequenceI getSrefSeq() + { + return seqRefIds.get(sref); + } + + public boolean isResolvable() + { + return seqRefIds.get(sref) != null; + } + + public SequenceI getSrefDatasetSeq() + { + SequenceI sq = seqRefIds.get(sref); + if (sq != null) + { + while (sq.getDatasetSequence() != null) + { + sq = sq.getDatasetSequence(); + } + } + return sq; + } + + /** + * @return true if the forward reference was fully resolved + */ + abstract boolean resolve(); + + @Override + public String toString() + { + return type + " reference to " + sref; + } + } + + /** + * create forward reference for a mapping + * + * @param sref + * @param _jmap + * @return + */ + public SeqFref newMappingRef(final String sref, + final jalview.datamodel.Mapping _jmap) + { + SeqFref fref = new SeqFref(sref, "Mapping") + { + public jalview.datamodel.Mapping jmap = _jmap; + + @Override + boolean resolve() + { + SequenceI seq = getSrefDatasetSeq(); + if (seq == null) + { + return false; + } + jmap.setTo(seq); + return true; + } + }; + return fref; + } + + public SeqFref newAlcodMapRef(final String sref, + final AlignedCodonFrame _cf, + final jalview.datamodel.Mapping _jmap) + { + + SeqFref fref = new SeqFref(sref, "Codon Frame") + { + AlignedCodonFrame cf = _cf; + + public jalview.datamodel.Mapping mp = _jmap; + + @Override + public boolean isResolvable() + { + return super.isResolvable() && mp.getTo() != null; + }; + + @Override + boolean resolve() + { + SequenceI seq = getSrefDatasetSeq(); + if (seq == null) + { + return false; + } + cf.addMap(seq, mp.getTo(), mp.getMap()); + return true; + } + }; + return fref; + } + public void resolveFrefedSequences() { - if (frefedSequence.size() > 0) + Iterator nextFref = frefedSequence.iterator(); + int toresolve = frefedSequence.size(); + int unresolved = 0, failedtoresolve = 0; + while (nextFref.hasNext()) { - int r = 0, rSize = frefedSequence.size(); - while (r < rSize) + SeqFref ref = nextFref.next(); + if (ref.isResolvable()) { - Object[] ref = frefedSequence.elementAt(r); - if (ref != null) + try { - String sref = (String) ref[0]; - if (seqRefIds.containsKey(sref)) + if (ref.resolve()) { - if (ref[1] instanceof jalview.datamodel.Mapping) - { - SequenceI seq = seqRefIds.get(sref); - while (seq.getDatasetSequence() != null) - { - seq = seq.getDatasetSequence(); - } - ((jalview.datamodel.Mapping) ref[1]).setTo(seq); - } - else - { - if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame) - { - SequenceI seq = seqRefIds.get(sref); - while (seq.getDatasetSequence() != null) - { - seq = seq.getDatasetSequence(); - } - if (ref[2] != null - && ref[2] instanceof jalview.datamodel.Mapping) - { - jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2]; - ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap( - seq, mp.getTo(), mp.getMap()); - } - else - { - System.err - .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving " - + ref[2].getClass() + " type objects."); - } - } - else - { - System.err - .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for " - + ref[1].getClass() + " type objects."); - } - } - frefedSequence.remove(r); - rSize--; + nextFref.remove(); } else { - System.err - .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string " - + ref[0] - + " with objecttype " - + ref[1].getClass()); - r++; + failedtoresolve++; } + } catch (Exception x) + { + System.err.println( + "IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence " + + ref.getSref()); + x.printStackTrace(); + failedtoresolve++; } - else + } + else + { + unresolved++; + } + } + if (unresolved > 0) + { + System.err.println("Jalview Project Import: There were " + unresolved + + " forward references left unresolved on the stack."); + } + if (failedtoresolve > 0) + { + System.err.println("SERIOUS! " + failedtoresolve + + " resolvable forward references failed to resolve."); + } + if (incompleteSeqs != null && incompleteSeqs.size() > 0) + { + System.err.println( + "Jalview Project Import: There are " + incompleteSeqs.size() + + " sequences which may have incomplete metadata."); + if (incompleteSeqs.size() < 10) + { + for (SequenceI s : incompleteSeqs.values()) { - // empty reference - frefedSequence.remove(r); - rSize--; + System.err.println(s.toString()); } } + else + { + System.err.println( + "Too many to report. Skipping output of incomplete sequences."); + } } } @@ -331,9 +432,9 @@ public class Jalview2XML * This maintains a map of viewports, the key being the seqSetId. Important to * set historyItem and redoList for multiple views */ - Map viewportsAdded = new HashMap(); + Map viewportsAdded = new HashMap<>(); - Map annotationIds = new HashMap(); + Map annotationIds = new HashMap<>(); String uniqueSetSuffix = ""; @@ -395,8 +496,21 @@ public class Jalview2XML { return; } + saveAllFrames(Arrays.asList(frames), jout); + } - Hashtable dsses = new Hashtable(); + /** + * core method for storing state for a set of AlignFrames. + * + * @param frames + * - frames involving all data to be exported (including containing + * splitframes) + * @param jout + * - project output stream + */ + private void saveAllFrames(List frames, JarOutputStream jout) + { + Hashtable dsses = new Hashtable<>(); /* * ensure cached data is clear before starting @@ -411,17 +525,16 @@ public class Jalview2XML // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS // ////////////////////////////////////////////////// - List shortNames = new ArrayList(); - List viewIds = new ArrayList(); + List shortNames = new ArrayList<>(); + List viewIds = new ArrayList<>(); // REVERSE ORDER - for (int i = frames.length - 1; i > -1; i--) + for (int i = frames.size() - 1; i > -1; i--) { - AlignFrame af = frames[i]; + AlignFrame af = frames.get(i); // skip ? - if (skipList != null - && skipList - .containsKey(af.getViewport().getSequenceSetId())) + if (skipList != null && skipList + .containsKey(af.getViewport().getSequenceSetId())) { continue; } @@ -441,8 +554,8 @@ public class Jalview2XML saveState(apanel, fileName, jout, viewIds); - String dssid = getDatasetIdRef(af.getViewport().getAlignment() - .getDataset()); + String dssid = getDatasetIdRef( + af.getViewport().getAlignment().getDataset()); if (!dsses.containsKey(dssid)) { dsses.put(dssid, af); @@ -488,8 +601,8 @@ public class Jalview2XML if (shortName.indexOf(File.separatorChar) > -1) { - shortName = shortName.substring(shortName - .lastIndexOf(File.separatorChar) + 1); + shortName = shortName + .substring(shortName.lastIndexOf(File.separatorChar) + 1); } int count = 1; @@ -520,30 +633,20 @@ public class Jalview2XML { try { - int ap = 0; - int apSize = af.alignPanels.size(); FileOutputStream fos = new FileOutputStream(jarFile); JarOutputStream jout = new JarOutputStream(fos); - Hashtable dsses = new Hashtable(); - List viewIds = new ArrayList(); + List frames = new ArrayList<>(); - for (AlignmentPanel apanel : af.alignPanels) + // resolve splitframes + if (af.getViewport().getCodingComplement() != null) { - String jfileName = apSize == 1 ? fileName : fileName + ap; - ap++; - if (!jfileName.endsWith(".xml")) - { - jfileName = jfileName + ".xml"; - } - saveState(apanel, jfileName, jout, viewIds); - String dssid = getDatasetIdRef(af.getViewport().getAlignment() - .getDataset()); - if (!dsses.containsKey(dssid)) - { - dsses.put(dssid, af); - } + frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames(); } - writeDatasetFor(dsses, fileName, jout); + else + { + frames.add(af); + } + saveAllFrames(frames, jout); try { jout.flush(); @@ -618,27 +721,32 @@ public class Jalview2XML { if (viewIds == null) { - viewIds = new ArrayList(); + viewIds = new ArrayList<>(); } initSeqRefs(); - List userColours = new ArrayList(); + List userColours = new ArrayList<>(); AlignViewport av = ap.av; + ViewportRanges vpRanges = av.getRanges(); JalviewModel object = new JalviewModel(); object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel()); object.setCreationDate(new java.util.Date(System.currentTimeMillis())); - object.setVersion(jalview.bin.Cache.getDefault("VERSION", - "Development Build")); + object.setVersion( + jalview.bin.Cache.getDefault("VERSION", "Development Build")); - jalview.datamodel.AlignmentI jal = av.getAlignment(); + /** + * rjal is full height alignment, jal is actual alignment with full metadata + * but excludes hidden sequences. + */ + jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal; if (av.hasHiddenRows()) { - jal = jal.getHiddenSequences().getFullAlignment(); + rjal = jal.getHiddenSequences().getFullAlignment(); } SequenceSet vamsasSet = new SequenceSet(); @@ -655,6 +763,7 @@ public class Jalview2XML { // switch jal and the dataset jal = jal.getDataset(); + rjal = jal; } } if (jal.getProperties() != null) @@ -671,39 +780,43 @@ public class Jalview2XML } JSeq jseq; - Set calcIdSet = new HashSet(); - + Set calcIdSet = new HashSet<>(); + // record the set of vamsas sequence XML POJO we create. + HashMap vamsasSetIds = new HashMap<>(); // SAVE SEQUENCES - for (int i = 0; i < jal.getHeight(); i++) + for (final SequenceI jds : rjal.getSequences()) { - final SequenceI jds = jal.getSequenceAt(i); final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds : jds.getDatasetSequence(); String id = seqHash(jds); - - if (seqRefIds.get(id) != null) - { - // This happens for two reasons: 1. multiple views are being serialised. - // 2. the hashCode has collided with another sequence's code. This DOES - // HAPPEN! (PF00072.15.stk does this) - // JBPNote: Uncomment to debug writing out of files that do not read - // back in due to ArrayOutOfBoundExceptions. - // System.err.println("vamsasSeq backref: "+id+""); - // System.err.println(jds.getName()+" - // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString()); - // System.err.println("Hashcode: "+seqHash(jds)); - // SequenceI rsq = (SequenceI) seqRefIds.get(id + ""); - // System.err.println(rsq.getName()+" - // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString()); - // System.err.println("Hashcode: "+seqHash(rsq)); - } - else - { - vamsasSeq = createVamsasSequence(id, jds); - vamsasSet.addSequence(vamsasSeq); - seqRefIds.put(id, jds); + if (vamsasSetIds.get(id) == null) + { + if (seqRefIds.get(id) != null && !storeDS) + { + // This happens for two reasons: 1. multiple views are being + // serialised. + // 2. the hashCode has collided with another sequence's code. This + // DOES + // HAPPEN! (PF00072.15.stk does this) + // JBPNote: Uncomment to debug writing out of files that do not read + // back in due to ArrayOutOfBoundExceptions. + // System.err.println("vamsasSeq backref: "+id+""); + // System.err.println(jds.getName()+" + // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString()); + // System.err.println("Hashcode: "+seqHash(jds)); + // SequenceI rsq = (SequenceI) seqRefIds.get(id + ""); + // System.err.println(rsq.getName()+" + // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString()); + // System.err.println("Hashcode: "+seqHash(rsq)); + } + else + { + vamsasSeq = createVamsasSequence(id, jds); + vamsasSet.addSequence(vamsasSeq); + vamsasSetIds.put(id, vamsasSeq); + seqRefIds.put(id, jds); + } } - jseq = new JSeq(); jseq.setStart(jds.getStart()); jseq.setEnd(jds.getEnd()); @@ -715,68 +828,70 @@ public class Jalview2XML // Store any sequences this sequence represents if (av.hasHiddenRows()) { - jseq.setHidden(av.getAlignment().getHiddenSequences() - .isHidden(jds)); + // use rjal, contains the full height alignment + jseq.setHidden( + av.getAlignment().getHiddenSequences().isHidden(jds)); - if (av.isHiddenRepSequence(jal.getSequenceAt(i))) + if (av.isHiddenRepSequence(jds)) { jalview.datamodel.SequenceI[] reps = av - .getRepresentedSequences(jal.getSequenceAt(i)) - .getSequencesInOrder(jal); + .getRepresentedSequences(jds).getSequencesInOrder(rjal); for (int h = 0; h < reps.length; h++) { - if (reps[h] != jal.getSequenceAt(i)) + if (reps[h] != jds) { - jseq.addHiddenSequences(jal.findIndex(reps[h])); + jseq.addHiddenSequences(rjal.findIndex(reps[h])); } } } } + // mark sequence as reference - if it is the reference for this view + if (jal.hasSeqrep()) + { + jseq.setViewreference(jds == jal.getSeqrep()); + } } - if (jds.getSequenceFeatures() != null) + // TODO: omit sequence features from each alignment view's XML dump if we + // are storing dataset + List sfs = jds + .getSequenceFeatures(); + for (SequenceFeature sf : sfs) { - jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures(); - int index = 0; - while (index < sf.length) - { - Features features = new Features(); + Features features = new Features(); - features.setBegin(sf[index].getBegin()); - features.setEnd(sf[index].getEnd()); - features.setDescription(sf[index].getDescription()); - features.setType(sf[index].getType()); - features.setFeatureGroup(sf[index].getFeatureGroup()); - features.setScore(sf[index].getScore()); - if (sf[index].links != null) + features.setBegin(sf.getBegin()); + features.setEnd(sf.getEnd()); + features.setDescription(sf.getDescription()); + features.setType(sf.getType()); + features.setFeatureGroup(sf.getFeatureGroup()); + features.setScore(sf.getScore()); + if (sf.links != null) + { + for (int l = 0; l < sf.links.size(); l++) { - for (int l = 0; l < sf[index].links.size(); l++) - { - OtherData keyValue = new OtherData(); - keyValue.setKey("LINK_" + l); - keyValue.setValue(sf[index].links.elementAt(l).toString()); - features.addOtherData(keyValue); - } + OtherData keyValue = new OtherData(); + keyValue.setKey("LINK_" + l); + keyValue.setValue(sf.links.elementAt(l).toString()); + features.addOtherData(keyValue); } - if (sf[index].otherDetails != null) + } + if (sf.otherDetails != null) + { + String key; + Iterator keys = sf.otherDetails.keySet().iterator(); + while (keys.hasNext()) { - String key; - Iterator keys = sf[index].otherDetails.keySet() - .iterator(); - while (keys.hasNext()) - { - key = keys.next(); - OtherData keyValue = new OtherData(); - keyValue.setKey(key); - keyValue.setValue(sf[index].otherDetails.get(key).toString()); - features.addOtherData(keyValue); - } + key = keys.next(); + OtherData keyValue = new OtherData(); + keyValue.setKey(key); + keyValue.setValue(sf.otherDetails.get(key).toString()); + features.addOtherData(keyValue); } - - jseq.addFeatures(features); - index++; } + + jseq.addFeatures(features); } if (jdatasq.getAllPDBEntries() != null) @@ -805,8 +920,8 @@ public class Jalview2XML if (frames[f] instanceof StructureViewerBase) { StructureViewerBase viewFrame = (StructureViewerBase) frames[f]; - matchedFile = saveStructureState(ap, jds, pdb, entry, - viewIds, matchedFile, viewFrame); + matchedFile = saveStructureState(ap, jds, pdb, entry, viewIds, + matchedFile, viewFrame); /* * Only store each structure viewer's state once in the project * jar. First time through only (storeDS==false) @@ -822,8 +937,8 @@ public class Jalview2XML viewerState.getBytes()); } catch (IOException e) { - System.err.println("Error saving viewer state: " - + e.getMessage()); + System.err.println( + "Error saving viewer state: " + e.getMessage()); } } } @@ -839,7 +954,7 @@ public class Jalview2XML pdb.setFile(matchedFile); // entry.getFile()); if (pdbfiles == null) { - pdbfiles = new ArrayList(); + pdbfiles = new ArrayList<>(); } if (!pdbfiles.contains(pdbId)) @@ -849,17 +964,16 @@ public class Jalview2XML } } - if (entry.getProperty() != null && !entry.getProperty().isEmpty()) + Enumeration props = entry.getProperties(); + if (props.hasMoreElements()) { PdbentryItem item = new PdbentryItem(); - Hashtable properties = entry.getProperty(); - Enumeration en2 = properties.keys(); - while (en2.hasMoreElements()) + while (props.hasMoreElements()) { Property prop = new Property(); - String key = en2.nextElement().toString(); + String key = props.nextElement(); prop.setName(key); - prop.setValue(properties.get(key).toString()); + prop.setValue(entry.getProperty(key).toString()); item.addProperty(prop); } pdb.addPdbentryItem(item); @@ -879,28 +993,34 @@ public class Jalview2XML jal = av.getAlignment(); } // SAVE MAPPINGS - if (jal.getCodonFrames() != null) + // FOR DATASET + if (storeDS && jal.getCodonFrames() != null) { List jac = jal.getCodonFrames(); for (AlignedCodonFrame acf : jac) { AlcodonFrame alc = new AlcodonFrame(); - vamsasSet.addAlcodonFrame(alc); if (acf.getProtMappings() != null && acf.getProtMappings().length > 0) { + boolean hasMap = false; SequenceI[] dnas = acf.getdnaSeqs(); jalview.datamodel.Mapping[] pmaps = acf.getProtMappings(); for (int m = 0; m < pmaps.length; m++) { AlcodMap alcmap = new AlcodMap(); alcmap.setDnasq(seqHash(dnas[m])); - alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null, - false)); + alcmap.setMapping( + createVamsasMapping(pmaps[m], dnas[m], null, false)); alc.addAlcodMap(alcmap); + hasMap = true; + } + if (hasMap) + { + vamsasSet.addAlcodonFrame(alc); } } - + // TODO: delete this ? dead code from 2.8.3->2.9 ? // { // AlcodonFrame alc = new AlcodonFrame(); // vamsasSet.addAlcodonFrame(alc); @@ -936,7 +1056,7 @@ public class Jalview2XML // SAVE TREES // ///////////////////////////////// - if (!storeDS && av.currentTree != null) + if (!storeDS && av.getCurrentTree() != null) { // FIND ANY ASSOCIATED TREES // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT @@ -954,8 +1074,8 @@ public class Jalview2XML { Tree tree = new Tree(); tree.setTitle(tp.getTitle()); - tree.setCurrentTree((av.currentTree == tp.getTree())); - tree.setNewick(tp.getTree().toString()); + tree.setCurrentTree((av.getCurrentTree() == tp.getTree())); + tree.setNewick(tp.getTree().print()); tree.setThreshold(tp.treeCanvas.threshold); tree.setFitToWindow(tp.fitToWindow.getState()); @@ -983,7 +1103,7 @@ public class Jalview2XML /** * store forward refs from an annotationRow to any groups */ - IdentityHashMap groupRefs = new IdentityHashMap(); + IdentityHashMap groupRefs = new IdentityHashMap<>(); if (storeDS) { for (SequenceI sq : jal.getSequences()) @@ -1025,38 +1145,42 @@ public class Jalview2XML // group has references so set its ID field jGroup.setId(groupRefs.get(sg)); } - if (sg.cs != null) + ColourSchemeI colourScheme = sg.getColourScheme(); + if (colourScheme != null) { - if (sg.cs.conservationApplied()) + ResidueShaderI groupColourScheme = sg.getGroupColourScheme(); + if (groupColourScheme.conservationApplied()) { - jGroup.setConsThreshold(sg.cs.getConservationInc()); + jGroup.setConsThreshold(groupColourScheme.getConservationInc()); - if (sg.cs instanceof jalview.schemes.UserColourScheme) + if (colourScheme instanceof jalview.schemes.UserColourScheme) { - jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms)); + jGroup.setColour( + setUserColourScheme(colourScheme, userColours, jms)); } else { - jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs)); + jGroup.setColour(colourScheme.getSchemeName()); } } - else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient) + else if (colourScheme instanceof jalview.schemes.AnnotationColourGradient) { jGroup.setColour("AnnotationColourGradient"); jGroup.setAnnotationColours(constructAnnotationColours( - (jalview.schemes.AnnotationColourGradient) sg.cs, + (jalview.schemes.AnnotationColourGradient) colourScheme, userColours, jms)); } - else if (sg.cs instanceof jalview.schemes.UserColourScheme) + else if (colourScheme instanceof jalview.schemes.UserColourScheme) { - jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms)); + jGroup.setColour( + setUserColourScheme(colourScheme, userColours, jms)); } else { - jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs)); + jGroup.setColour(colourScheme.getSchemeName()); } - jGroup.setPidThreshold(sg.cs.getThreshold()); + jGroup.setPidThreshold(groupColourScheme.getThreshold()); } jGroup.setOutlineColour(sg.getOutlineColour().getRGB()); @@ -1084,8 +1208,8 @@ public class Jalview2XML // /////////SAVE VIEWPORT Viewport view = new Viewport(); view.setTitle(ap.alignFrame.getTitle()); - view.setSequenceSetId(makeHashCode(av.getSequenceSetId(), - av.getSequenceSetId())); + view.setSequenceSetId( + makeHashCode(av.getSequenceSetId(), av.getSequenceSetId())); view.setId(av.getViewId()); if (av.getCodingComplement() != null) { @@ -1115,15 +1239,16 @@ public class Jalview2XML view.setWidth(size.width); view.setHeight(size.height); - view.setStartRes(av.startRes); - view.setStartSeq(av.startSeq); + view.setStartRes(vpRanges.getStartRes()); + view.setStartSeq(vpRanges.getStartSeq()); if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme) { view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(), userColours, jms)); } - else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient) + else if (av + .getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient) { AnnotationColours ac = constructAnnotationColours( (jalview.schemes.AnnotationColourGradient) av @@ -1135,27 +1260,24 @@ public class Jalview2XML } else { - view.setBgColour(ColourSchemeProperty.getColourName(av - .getGlobalColourScheme())); + view.setBgColour(ColourSchemeProperty + .getColourName(av.getGlobalColourScheme())); } + ResidueShaderI vcs = av.getResidueShading(); ColourSchemeI cs = av.getGlobalColourScheme(); if (cs != null) { - if (cs.conservationApplied()) + if (vcs.conservationApplied()) { - view.setConsThreshold(cs.getConservationInc()); + view.setConsThreshold(vcs.getConservationInc()); if (cs instanceof jalview.schemes.UserColourScheme) { view.setBgColour(setUserColourScheme(cs, userColours, jms)); } } - - if (cs instanceof ResidueColourScheme) - { - view.setPidThreshold(cs.getThreshold()); - } + view.setPidThreshold(vcs.getThreshold()); } view.setConservationSelected(av.getConservationSelected()); @@ -1195,36 +1317,35 @@ public class Jalview2XML .getFeatureRenderer().getRenderOrder() .toArray(new String[0]); - Vector settingsAdded = new Vector(); - Object gstyle = null; - GraduatedColor gcol = null; + Vector settingsAdded = new Vector<>(); if (renderOrder != null) { for (String featureType : renderOrder) { - gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer() - .getFeatureStyle(featureType); + FeatureColourI fcol = ap.getSeqPanel().seqCanvas + .getFeatureRenderer().getFeatureStyle(featureType); Setting setting = new Setting(); setting.setType(featureType); - if (gstyle instanceof GraduatedColor) + if (!fcol.isSimpleColour()) { - gcol = (GraduatedColor) gstyle; - setting.setColour(gcol.getMaxColor().getRGB()); - setting.setMincolour(gcol.getMinColor().getRGB()); - setting.setMin(gcol.getMin()); - setting.setMax(gcol.getMax()); - setting.setColourByLabel(gcol.isColourByLabel()); - setting.setAutoScale(gcol.isAutoScale()); - setting.setThreshold(gcol.getThresh()); - setting.setThreshstate(gcol.getThreshType()); + setting.setColour(fcol.getMaxColour().getRGB()); + setting.setMincolour(fcol.getMinColour().getRGB()); + setting.setMin(fcol.getMin()); + setting.setMax(fcol.getMax()); + setting.setColourByLabel(fcol.isColourByLabel()); + setting.setAutoScale(fcol.isAutoScaled()); + setting.setThreshold(fcol.getThreshold()); + // -1 = No threshold, 0 = Below, 1 = Above + setting.setThreshstate(fcol.isAboveThreshold() ? 1 + : (fcol.isBelowThreshold() ? 0 : -1)); } else { - setting.setColour(((Color) gstyle).getRGB()); + setting.setColour(fcol.getColour().getRGB()); } - setting.setDisplay(av.getFeaturesDisplayed().isVisible( - featureType)); + setting.setDisplay( + av.getFeaturesDisplayed().isVisible(featureType)); float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer() .getOrder(featureType); if (rorder > -1) @@ -1238,9 +1359,8 @@ public class Jalview2XML // is groups actually supposed to be a map here ? Iterator en = ap.getSeqPanel().seqCanvas - .getFeatureRenderer() - .getFeatureGroups().iterator(); - Vector groupsAdded = new Vector(); + .getFeatureRenderer().getFeatureGroups().iterator(); + Vector groupsAdded = new Vector<>(); while (en.hasNext()) { String grp = en.next(); @@ -1252,28 +1372,26 @@ public class Jalview2XML g.setName(grp); g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas .getFeatureRenderer().checkGroupVisibility(grp, false)) - .booleanValue()); + .booleanValue()); fs.addGroup(g); groupsAdded.addElement(grp); } jms.setFeatureSettings(fs); - } if (av.hasHiddenColumns()) { - if (av.getColumnSelection() == null - || av.getColumnSelection().getHiddenColumns() == null) + jalview.datamodel.HiddenColumns hidden = av.getAlignment() + .getHiddenColumns(); + if (hidden == null) { warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this."); } else { - for (int c = 0; c < av.getColumnSelection().getHiddenColumns() - .size(); c++) + ArrayList hiddenRegions = hidden.getHiddenColumnsCopy(); + for (int[] region : hiddenRegions) { - int[] region = av.getColumnSelection().getHiddenColumns() - .get(c); HiddenColumns hc = new HiddenColumns(); hc.setStart(region[0]); hc.setEnd(region[1]); @@ -1312,8 +1430,8 @@ public class Jalview2XML System.out.println("Writing jar entry " + fileName); JarEntry entry = new JarEntry(fileName); jout.putNextEntry(entry); - PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout, - UTF_8)); + PrintWriter pout = new PrintWriter( + new OutputStreamWriter(jout, UTF_8)); Marshaller marshaller = new Marshaller(pout); marshaller.marshal(object); pout.flush(); @@ -1514,8 +1632,8 @@ public class Jalview2XML final PDBEntry pdbentry = bindingModel.getPdbEntry(peid); final String pdbId = pdbentry.getId(); if (!pdbId.equals(entry.getId()) - && !(entry.getId().length() > 4 && entry.getId() - .toLowerCase().startsWith(pdbId.toLowerCase()))) + && !(entry.getId().length() > 4 && entry.getId().toLowerCase() + .startsWith(pdbId.toLowerCase()))) { /* * not interested in a binding to a different PDB entry here @@ -1528,8 +1646,8 @@ public class Jalview2XML } else if (!matchedFile.equals(pdbentry.getFile())) { - Cache.log - .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): " + Cache.log.warn( + "Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): " + pdbentry.getFile()); } // record the @@ -1538,7 +1656,8 @@ public class Jalview2XML // match is ambiguous (e.g. // 1QIP==1qipA) - for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++) + for (int smap = 0; smap < viewFrame.getBinding() + .getSequence()[peid].length; smap++) { // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1) if (jds == viewFrame.getBinding().getSequence()[peid][smap]) @@ -1562,6 +1681,15 @@ public class Jalview2XML return matchedFile; } + /** + * Populates the AnnotationColours xml for save. This captures the settings of + * the options in the 'Colour by Annotation' dialog. + * + * @param acg + * @param userColours + * @param jms + * @return + */ private AnnotationColours constructAnnotationColours( AnnotationColourGradient acg, List userColours, JalviewModelSequence jms) @@ -1569,16 +1697,17 @@ public class Jalview2XML AnnotationColours ac = new AnnotationColours(); ac.setAboveThreshold(acg.getAboveThreshold()); ac.setThreshold(acg.getAnnotationThreshold()); - ac.setAnnotation(acg.getAnnotation()); - if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme) + // 2.10.2 save annotationId (unique) not annotation label + ac.setAnnotation(acg.getAnnotation().annotationId); + if (acg.getBaseColour() instanceof UserColourScheme) { - ac.setColourScheme(setUserColourScheme(acg.getBaseColour(), - userColours, jms)); + ac.setColourScheme( + setUserColourScheme(acg.getBaseColour(), userColours, jms)); } else { - ac.setColourScheme(ColourSchemeProperty.getColourName(acg - .getBaseColour())); + ac.setColourScheme( + ColourSchemeProperty.getColourName(acg.getBaseColour())); } ac.setMaxColour(acg.getMaxColour().getRGB()); @@ -1621,11 +1750,10 @@ public class Jalview2XML if (groupIdr == null) { // make a locally unique String - groupRefs.put( - annotation.groupRef, + groupRefs.put(annotation.groupRef, groupIdr = ("" + System.currentTimeMillis() - + annotation.groupRef.getName() + groupRefs - .size())); + + annotation.groupRef.getName() + + groupRefs.size())); } an.setGroupRef(groupIdr.toString()); } @@ -1705,7 +1833,8 @@ public class Jalview2XML } if (annotation.annotations[a].displayCharacter != null) { - ae.setDisplayCharacter(annotation.annotations[a].displayCharacter); + ae.setDisplayCharacter( + annotation.annotations[a].displayCharacter); } if (!Float.isNaN(annotation.annotations[a].value)) @@ -1716,8 +1845,8 @@ public class Jalview2XML ae.setPosition(a); if (annotation.annotations[a].secondaryStructure > ' ') { - ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure - + ""); + ae.setSecondaryStructure( + annotation.annotations[a].secondaryStructure + ""); } if (annotation.annotations[a].colour != null @@ -1779,8 +1908,8 @@ public class Jalview2XML // need to be able to recover 1) settings 2) user-defined presets or // recreate settings from preset 3) predefined settings provided by // service - or settings that can be transferred (or discarded) - vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n", - "|\\n|")); + vCalcIdParam.setParameters( + settings.getWsParamFile().replace("\n", "|\\n|")); vCalcIdParam.setAutoUpdate(settings.isAutoUpdate()); // todo - decide if updateImmediately is needed for any projects. @@ -1840,8 +1969,8 @@ public class Jalview2XML } } throw new Error(MessageManager.formatMessage( - "error.unsupported_version_calcIdparam", - new Object[] { calcIdParam.toString() })); + "error.unsupported_version_calcIdparam", new Object[] + { calcIdParam.toString() })); } /** @@ -1923,16 +2052,17 @@ public class Jalview2XML if (jds.getDatasetSequence() != null) { vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence())); - if (jds.getDatasetSequence().getDBRefs() != null) - { - dbrefs = jds.getDatasetSequence().getDBRefs(); - } } else { - vamsasSeq.setDsseqid(id); // so we can tell which sequences really are + // seqId==dsseqid so we can tell which sequences really are // dataset sequences only + vamsasSeq.setDsseqid(id); dbrefs = jds.getDBRefs(); + if (parentseq == null) + { + parentseq = jds; + } } if (dbrefs != null) { @@ -1984,38 +2114,32 @@ public class Jalview2XML if (jmp.getTo() != null) { MappingChoice mpc = new MappingChoice(); - if (recurse - && (parentseq != jmp.getTo() || parentseq - .getDatasetSequence() != jmp.getTo())) + + // check/create ID for the sequence referenced by getTo() + + String jmpid = ""; + SequenceI ps = null; + if (parentseq != jmp.getTo() + && parentseq.getDatasetSequence() != jmp.getTo()) { - mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()), - jmp.getTo(), jds)); + // chaining dbref rather than a handshaking one + jmpid = seqHash(ps = jmp.getTo()); } else { - String jmpid = ""; - SequenceI ps = null; - if (parentseq != jmp.getTo() - && parentseq.getDatasetSequence() != jmp.getTo()) - { - // chaining dbref rather than a handshaking one - jmpid = seqHash(ps = jmp.getTo()); - } - else - { - jmpid = seqHash(ps = parentseq); - } - mpc.setDseqFor(jmpid); - if (!seqRefIds.containsKey(mpc.getDseqFor())) - { - jalview.bin.Cache.log.debug("creatign new DseqFor ID"); - seqRefIds.put(mpc.getDseqFor(), ps); - } - else - { - jalview.bin.Cache.log.debug("reusing DseqFor ID"); - } + jmpid = seqHash(ps = parentseq); + } + mpc.setDseqFor(jmpid); + if (!seqRefIds.containsKey(mpc.getDseqFor())) + { + jalview.bin.Cache.log.debug("creatign new DseqFor ID"); + seqRefIds.put(mpc.getDseqFor(), ps); + } + else + { + jalview.bin.Cache.log.debug("reusing DseqFor ID"); } + mp.setMappingChoice(mpc); } } @@ -2088,8 +2212,8 @@ public class Jalview2XML for (int i = 0; i < 24; i++) { - newColours[i] = new java.awt.Color(Integer.parseInt(colours - .getUserColourScheme().getColour(i).getRGB(), 16)); + newColours[i] = new java.awt.Color(Integer.parseInt( + colours.getUserColourScheme().getColour(i).getRGB(), 16)); } jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme( @@ -2100,8 +2224,9 @@ public class Jalview2XML newColours = new java.awt.Color[23]; for (int i = 0; i < 23; i++) { - newColours[i] = new java.awt.Color(Integer.parseInt(colours - .getUserColourScheme().getColour(i + 24).getRGB(), 16)); + newColours[i] = new java.awt.Color(Integer.parseInt( + colours.getUserColourScheme().getColour(i + 24).getRGB(), + 16)); } ucs.setLowerCaseColours(newColours); } @@ -2134,7 +2259,7 @@ public class Jalview2XML try { // create list to store references for any new Jmol viewers created - newStructureViewers = new Vector(); + newStructureViewers = new Vector<>(); // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING // Workaround is to make sure caller implements the JarInputStreamProvider // interface @@ -2142,6 +2267,7 @@ public class Jalview2XML jarInputStreamProvider jprovider = createjarInputStreamProvider(file); af = loadJalviewAlign(jprovider); + af.setMenusForViewport(); } catch (MalformedURLException e) { @@ -2224,15 +2350,11 @@ public class Jalview2XML } if (seqRefIds == null) { - seqRefIds = new HashMap(); - } - if (frefedSequence == null) - { - frefedSequence = new Vector(); + initSeqRefs(); } - AlignFrame af = null, _af = null; - Map gatherToThisFrame = new HashMap(); + IdentityHashMap importedDatasets = new IdentityHashMap<>(); + Map gatherToThisFrame = new HashMap<>(); final String file = jprovider.getFilename(); try { @@ -2259,13 +2381,24 @@ public class Jalview2XML if (true) // !skipViewport(object)) { _af = loadFromObject(object, file, true, jprovider); - if (object.getJalviewModelSequence().getViewportCount() > 0) + if (_af != null && object.getJalviewModelSequence() + .getViewportCount() > 0) { - af = _af; - if (af.viewport.isGatherViewsHere()) + if (af == null) { - gatherToThisFrame.put(af.viewport.getSequenceSetId(), af); + // store a reference to the first view + af = _af; } + if (_af.viewport.isGatherViewsHere()) + { + // if this is a gathered view, keep its reference since + // after gathering views, only this frame will remain + af = _af; + gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af); + } + // Save dataset to register mappings once all resolved + importedDatasets.put(af.viewport.getAlignment().getDataset(), + af.viewport.getAlignment().getDataset()); } } entryCount++; @@ -2281,8 +2414,8 @@ public class Jalview2XML { ex.printStackTrace(); errorMessage = "Couldn't locate Jalview XML file : " + file; - System.err.println("Exception whilst loading jalview XML file : " - + ex + "\n"); + System.err.println( + "Exception whilst loading jalview XML file : " + ex + "\n"); } catch (Exception ex) { System.err.println("Parsing as Jalview Version 2 file failed."); @@ -2311,8 +2444,8 @@ public class Jalview2XML } ex.printStackTrace(); - System.err.println("Exception whilst loading jalview XML file : " - + ex + "\n"); + System.err.println( + "Exception whilst loading jalview XML file : " + ex + "\n"); } catch (OutOfMemoryError e) { // Don't use the OOM Window here @@ -2321,11 +2454,6 @@ public class Jalview2XML e.printStackTrace(); } - if (Desktop.instance != null) - { - Desktop.instance.stopLoading(); - } - /* * Regather multiple views (with the same sequence set id) to the frame (if * any) that is flagged as the one to gather to, i.e. convert them to tabbed @@ -2339,11 +2467,25 @@ public class Jalview2XML } restoreSplitFrames(); - + for (AlignmentI ds : importedDatasets.keySet()) + { + if (ds.getCodonFrames() != null) + { + StructureSelectionManager + .getStructureSelectionManager(Desktop.instance) + .registerMappings(ds.getCodonFrames()); + } + } if (errorMessage != null) { reportErrors(); } + + if (Desktop.instance != null) + { + Desktop.instance.stopLoading(); + } + return af; } @@ -2354,9 +2496,9 @@ public class Jalview2XML */ protected void restoreSplitFrames() { - List gatherTo = new ArrayList(); - List addedToSplitFrames = new ArrayList(); - Map dna = new HashMap(); + List gatherTo = new ArrayList<>(); + List addedToSplitFrames = new ArrayList<>(); + Map dna = new HashMap<>(); /* * Identify the DNA alignments @@ -2388,6 +2530,8 @@ public class Jalview2XML SplitFrame sf = createSplitFrame(dnaFrame, af); addedToSplitFrames.add(dnaFrame); addedToSplitFrames.add(af); + dnaFrame.setMenusForViewport(); + af.setMenusForViewport(); if (af.viewport.isGatherViewsHere()) { gatherTo.add(sf); @@ -2409,6 +2553,7 @@ public class Jalview2XML Viewport view = candidate.getKey(); Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), view.getHeight()); + af.setMenusForViewport(); System.err.println("Failed to restore view " + view.getTitle() + " to split frame"); } @@ -2478,10 +2623,11 @@ public class Jalview2XML @Override public void run() { - JOptionPane.showInternalMessageDialog(Desktop.desktop, - finalErrorMessage, "Error " - + (saving ? "saving" : "loading") - + " Jalview file", JOptionPane.WARNING_MESSAGE); + JvOptionPane.showInternalMessageDialog(Desktop.desktop, + finalErrorMessage, + "Error " + (saving ? "saving" : "loading") + + " Jalview file", + JvOptionPane.WARNING_MESSAGE); } }); } @@ -2493,7 +2639,7 @@ public class Jalview2XML errorMessage = null; } - Map alreadyLoadedPDB = new HashMap(); + Map alreadyLoadedPDB = new HashMap<>(); /** * when set, local views will be updated from view stored in JalviewXML @@ -2512,14 +2658,16 @@ public class Jalview2XML * @param pdbId * @return */ - String loadPDBFile(jarInputStreamProvider jprovider, String pdbId) + String loadPDBFile(jarInputStreamProvider jprovider, String pdbId, + String origFile) { if (alreadyLoadedPDB.containsKey(pdbId)) { return alreadyLoadedPDB.get(pdbId).toString(); } - String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb"); + String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb", + origFile); if (tempFile != null) { alreadyLoadedPDB.put(pdbId, tempFile); @@ -2536,14 +2684,26 @@ public class Jalview2XML * @param prefix * a prefix for the temporary file name, must be at least three * characters long + * @param origFile + * null or original file - so new file can be given the same suffix + * as the old one * @return */ protected String copyJarEntry(jarInputStreamProvider jprovider, - String jarEntryName, String prefix) + String jarEntryName, String prefix, String origFile) { BufferedReader in = null; PrintWriter out = null; - + String suffix = ".tmp"; + if (origFile == null) + { + origFile = jarEntryName; + } + int sfpos = origFile.lastIndexOf("."); + if (sfpos > -1 && sfpos < (origFile.length() - 3)) + { + suffix = "." + origFile.substring(sfpos + 1); + } try { JarInputStream jin = jprovider.getJarInputStream(); @@ -2561,7 +2721,7 @@ public class Jalview2XML if (entry != null) { in = new BufferedReader(new InputStreamReader(jin, UTF_8)); - File outFile = File.createTempFile(prefix, ".tmp"); + File outFile = File.createTempFile(prefix, suffix); outFile.deleteOnExit(); out = new PrintWriter(new FileOutputStream(outFile)); String data; @@ -2649,46 +2809,80 @@ public class Jalview2XML // LOAD SEQUENCES List hiddenSeqs = null; - jalview.datamodel.Sequence jseq; - List tmpseqs = new ArrayList(); + List tmpseqs = new ArrayList<>(); boolean multipleView = false; - + SequenceI referenceseqForView = null; JSeq[] jseqs = object.getJalviewModelSequence().getJSeq(); int vi = 0; // counter in vamsasSeq array for (int i = 0; i < jseqs.length; i++) { String seqId = jseqs[i].getId(); - if (seqRefIds.get(seqId) != null) + SequenceI tmpSeq = seqRefIds.get(seqId); + if (tmpSeq != null) { - tmpseqs.add(seqRefIds.get(seqId)); - multipleView = true; + if (!incompleteSeqs.containsKey(seqId)) + { + // may not need this check, but keep it for at least 2.9,1 release + if (tmpSeq.getStart() != jseqs[i].getStart() + || tmpSeq.getEnd() != jseqs[i].getEnd()) + { + System.err.println( + "Warning JAL-2154 regression: updating start/end for sequence " + + tmpSeq.toString() + " to " + jseqs[i]); + } + } + else + { + incompleteSeqs.remove(seqId); + } + if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId)) + { + // most likely we are reading a dataset XML document so + // update from vamsasSeq section of XML for this sequence + tmpSeq.setName(vamsasSeq[vi].getName()); + tmpSeq.setDescription(vamsasSeq[vi].getDescription()); + tmpSeq.setSequence(vamsasSeq[vi].getSequence()); + vi++; + } + else + { + // reading multiple views, so vamsasSeq set is a subset of JSeq + multipleView = true; + } + tmpSeq.setStart(jseqs[i].getStart()); + tmpSeq.setEnd(jseqs[i].getEnd()); + tmpseqs.add(tmpSeq); } else { - jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(), + tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(), vamsasSeq[vi].getSequence()); - jseq.setDescription(vamsasSeq[vi].getDescription()); - jseq.setStart(jseqs[i].getStart()); - jseq.setEnd(jseqs[i].getEnd()); - jseq.setVamsasId(uniqueSetSuffix + seqId); - seqRefIds.put(vamsasSeq[vi].getId(), jseq); - tmpseqs.add(jseq); + tmpSeq.setDescription(vamsasSeq[vi].getDescription()); + tmpSeq.setStart(jseqs[i].getStart()); + tmpSeq.setEnd(jseqs[i].getEnd()); + tmpSeq.setVamsasId(uniqueSetSuffix + seqId); + seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq); + tmpseqs.add(tmpSeq); vi++; } + if (jseqs[i].hasViewreference() && jseqs[i].getViewreference()) + { + referenceseqForView = tmpseqs.get(tmpseqs.size() - 1); + } + if (jseqs[i].getHidden()) { if (hiddenSeqs == null) { - hiddenSeqs = new ArrayList(); + hiddenSeqs = new ArrayList<>(); } - hiddenSeqs.add(seqRefIds.get(seqId)); + hiddenSeqs.add(tmpSeq); } - } // / @@ -2697,31 +2891,52 @@ public class Jalview2XML SequenceI[] orderedSeqs = tmpseqs .toArray(new SequenceI[tmpseqs.size()]); - Alignment al = new Alignment(orderedSeqs); - - // / Add the alignment properties - for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++) - { - SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i); - al.setProperty(ssp.getKey(), ssp.getValue()); - } - - // / - // SequenceFeatures are added to the DatasetSequence, - // so we must create or recover the dataset before loading features + AlignmentI al = null; + // so we must create or recover the dataset alignment before going further // /////////////////////////////// if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "") { - // older jalview projects do not have a dataset id. + // older jalview projects do not have a dataset - so creat alignment and + // dataset + al = new Alignment(orderedSeqs); al.setDataset(null); } else { - // recover dataset - passing on flag indicating if this a 'viewless' - // sequence set (a.k.a. a stored dataset for the project) - recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence() - .getViewportCount() == 0); + boolean isdsal = object.getJalviewModelSequence() + .getViewportCount() == 0; + if (isdsal) + { + // we are importing a dataset record, so + // recover reference to an alignment already materialsed as dataset + al = getDatasetFor(vamsasSet.getDatasetId()); + } + if (al == null) + { + // materialse the alignment + al = new Alignment(orderedSeqs); + } + if (isdsal) + { + addDatasetRef(vamsasSet.getDatasetId(), al); + } + + // finally, verify all data in vamsasSet is actually present in al + // passing on flag indicating if it is actually a stored dataset + recoverDatasetFor(vamsasSet, al, isdsal); + } + + if (referenceseqForView != null) + { + al.setSeqrep(referenceseqForView); + } + // / Add the alignment properties + for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++) + { + SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i); + al.setProperty(ssp.getKey(), ssp.getValue()); } + // /////////////////////////////// Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this?? @@ -2729,6 +2944,12 @@ public class Jalview2XML { // load sequence features, database references and any associated PDB // structures for the alignment + // + // prior to 2.10, this part would only be executed the first time a + // sequence was encountered, but not afterwards. + // now, for 2.10 projects, this is also done if the xml doc includes + // dataset sequences not actually present in any particular view. + // for (int i = 0; i < vamsasSeq.length; i++) { if (jseqs[i].getFeaturesCount() > 0) @@ -2736,12 +2957,11 @@ public class Jalview2XML Features[] features = jseqs[i].getFeatures(); for (int f = 0; f < features.length; f++) { - jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature( - features[f].getType(), features[f].getDescription(), - features[f].getStatus(), features[f].getBegin(), - features[f].getEnd(), features[f].getFeatureGroup()); - - sf.setScore(features[f].getScore()); + SequenceFeature sf = new SequenceFeature(features[f].getType(), + features[f].getDescription(), features[f].getBegin(), + features[f].getEnd(), features[f].getScore(), + features[f].getFeatureGroup()); + sf.setStatus(features[f].getStatus()); for (int od = 0; od < features[f].getOtherDataCount(); od++) { OtherData keyValue = features[f].getOtherData(od); @@ -2755,13 +2975,18 @@ public class Jalview2XML } } - - al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf); + // adds feature to datasequence's feature set (since Jalview 2.10) + al.getSequenceAt(i).addSequenceFeature(sf); } } if (vamsasSeq[i].getDBRefCount() > 0) { - addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]); + // adds dbrefs to datasequence's set (since Jalview 2.10) + addDBRefs( + al.getSequenceAt(i).getDatasetSequence() == null + ? al.getSequenceAt(i) + : al.getSequenceAt(i).getDatasetSequence(), + vamsasSeq[i]); } if (jseqs[i].getPdbidsCount() > 0) { @@ -2772,29 +2997,50 @@ public class Jalview2XML entry.setId(ids[p].getId()); if (ids[p].getType() != null) { - if (ids[p].getType().equalsIgnoreCase("PDB")) + if (PDBEntry.Type.getType(ids[p].getType()) != null) { - entry.setType(PDBEntry.Type.PDB); + entry.setType(PDBEntry.Type.getType(ids[p].getType())); } else { entry.setType(PDBEntry.Type.FILE); } } - if (ids[p].getFile() != null) + // jprovider is null when executing 'New View' + if (ids[p].getFile() != null && jprovider != null) { if (!pdbloaded.containsKey(ids[p].getFile())) { - entry.setFile(loadPDBFile(jprovider, ids[p].getId())); + entry.setFile(loadPDBFile(jprovider, ids[p].getId(), + ids[p].getFile())); } else { entry.setFile(pdbloaded.get(ids[p].getId()).toString()); } } - StructureSelectionManager.getStructureSelectionManager( - Desktop.instance).registerPDBEntry(entry); - al.getSequenceAt(i).getDatasetSequence().addPDBId(entry); + if (ids[p].getPdbentryItem() != null) + { + for (PdbentryItem item : ids[p].getPdbentryItem()) + { + for (Property pr : item.getProperty()) + { + entry.setProperty(pr.getName(), pr.getValue()); + } + } + } + StructureSelectionManager + .getStructureSelectionManager(Desktop.instance) + .registerPDBEntry(entry); + // adds PDBEntry to datasequence's set (since Jalview 2.10) + if (al.getSequenceAt(i).getDatasetSequence() != null) + { + al.getSequenceAt(i).getDatasetSequence().addPDBId(entry); + } + else + { + al.getSequenceAt(i).addPDBId(entry); + } } } } @@ -2823,31 +3069,31 @@ public class Jalview2XML if (maps[m].getMapping() != null) { mapping = addMapping(maps[m].getMapping()); - } - if (dnaseq != null && mapping.getTo() != null) - { - cf.addMap(dnaseq, mapping.getTo(), mapping.getMap()); - } - else - { - // defer to later - frefedSequence.add(new Object[] { maps[m].getDnasq(), cf, - mapping }); + if (dnaseq != null && mapping.getTo() != null) + { + cf.addMap(dnaseq, mapping.getTo(), mapping.getMap()); + } + else + { + // defer to later + frefedSequence.add( + newAlcodMapRef(maps[m].getDnasq(), cf, mapping)); + } } } + al.addCodonFrame(cf); } - al.addCodonFrame(cf); } } // //////////////////////////////// // LOAD ANNOTATIONS - List autoAlan = new ArrayList(); + List autoAlan = new ArrayList<>(); /* * store any annotations which forward reference a group's ID */ - Map> groupAnnotRefs = new Hashtable>(); + Map> groupAnnotRefs = new Hashtable<>(); if (vamsasSet.getAnnotationCount() > 0) { @@ -2872,9 +3118,8 @@ public class Jalview2XML annotation.setAutoCalculated(true); } } - if (autoForView - || (annotation.hasAutoCalculated() && annotation - .isAutoCalculated())) + if (autoForView || (annotation.hasAutoCalculated() + && annotation.isAutoCalculated())) { // remove ID - we don't recover annotation from other views for // view-specific annotation @@ -2916,10 +3161,12 @@ public class Jalview2XML anot[anpos] = new jalview.datamodel.Annotation( - ae[aa].getDisplayCharacter(), ae[aa].getDescription(), - (ae[aa].getSecondaryStructure() == null || ae[aa] - .getSecondaryStructure().length() == 0) ? ' ' - : ae[aa].getSecondaryStructure().charAt(0), + ae[aa].getDisplayCharacter(), ae[aa].getDescription(), + (ae[aa].getSecondaryStructure() == null + || ae[aa].getSecondaryStructure().length() == 0) + ? ' ' + : ae[aa].getSecondaryStructure() + .charAt(0), ae[aa].getValue() ); @@ -2953,10 +3200,11 @@ public class Jalview2XML jaa._linecolour = firstColour; if (annotation.getThresholdLine() != null) { - jaa.setThreshold(new jalview.datamodel.GraphLine(annotation - .getThresholdLine().getValue(), annotation - .getThresholdLine().getLabel(), new java.awt.Color( - annotation.getThresholdLine().getColour()))); + jaa.setThreshold(new jalview.datamodel.GraphLine( + annotation.getThresholdLine().getValue(), + annotation.getThresholdLine().getLabel(), + new java.awt.Color( + annotation.getThresholdLine().getColour()))); } if (autoForView || annotation.isAutoCalculated()) @@ -3002,7 +3250,7 @@ public class Jalview2XML .get(an[i].getGroupRef()); if (aal == null) { - aal = new ArrayList(); + aal = new ArrayList<>(); groupAnnotRefs.put(an[i].getGroupRef(), aal); } aal.add(jaa); @@ -3084,20 +3332,16 @@ public class Jalview2XML && jGroup.getAnnotationColours() != null) { addAnnotSchemeGroup = true; - cs = null; } else { - cs = ColourSchemeProperty.getColour(al, jGroup.getColour()); - } - - if (cs != null) - { - cs.setThreshold(jGroup.getPidThreshold(), true); + cs = ColourSchemeProperty.getColourScheme(al, + jGroup.getColour()); } } + int pidThreshold = jGroup.getPidThreshold(); - Vector seqs = new Vector(); + Vector seqs = new Vector<>(); for (int s = 0; s < jGroup.getSeqCount(); s++) { @@ -3118,13 +3362,16 @@ public class Jalview2XML SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs, jGroup.getDisplayBoxes(), jGroup.getDisplayText(), jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd()); - + sg.getGroupColourScheme().setThreshold(pidThreshold, true); + sg.getGroupColourScheme() + .setConservationInc(jGroup.getConsThreshold()); sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour())); sg.textColour = new java.awt.Color(jGroup.getTextCol1()); sg.textColour2 = new java.awt.Color(jGroup.getTextCol2()); - sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup - .isShowUnconserved() : false); + sg.setShowNonconserved( + jGroup.hasShowUnconserved() ? jGroup.isShowUnconserved() + : false); sg.thresholdTextColour = jGroup.getTextColThreshold(); if (jGroup.hasShowConsensusHistogram()) { @@ -3145,9 +3392,8 @@ public class Jalview2XML } if (jGroup.getConsThreshold() != 0) { - jalview.analysis.Conservation c = new jalview.analysis.Conservation( - "All", ResidueProperties.propHash, 3, - sg.getSequences(null), 0, sg.getWidth() - 1); + Conservation c = new Conservation("All", sg.getSequences(null), 0, + sg.getWidth() - 1); c.calculate(); c.verdict(false, 25); sg.cs.setConservation(c); @@ -3156,8 +3402,8 @@ public class Jalview2XML if (jGroup.getId() != null && groupAnnotRefs.size() > 0) { // re-instate unique group/annotation row reference - List jaal = groupAnnotRefs.get(jGroup - .getId()); + List jaal = groupAnnotRefs + .get(jGroup.getId()); if (jaal != null) { for (AlignmentAnnotation jaa : jaal) @@ -3185,8 +3431,8 @@ public class Jalview2XML if (addAnnotSchemeGroup) { // reconstruct the annotation colourscheme - sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(), - null, al, jms, false); + sg.setColourScheme(constructAnnotationColour( + jGroup.getAnnotationColours(), null, al, jms, false)); } } } @@ -3203,8 +3449,8 @@ public class Jalview2XML // to the same sequenceSet. We must modify this id on load // so that each load of the file gives a unique id String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix; - String viewId = (view.getId() == null ? null : view.getId() - + uniqueSetSuffix); + String viewId = (view.getId() == null ? null + : view.getId() + uniqueSetSuffix); AlignFrame af = null; AlignViewport av = null; // now check to see if we really need to create a new viewport. @@ -3217,8 +3463,8 @@ public class Jalview2XML // XML. // and then recover its containing af to allow the settings to be applied. // TODO: fix for vamsas demo - System.err - .println("About to recover a viewport for existing alignment: Sequence set ID is " + System.err.println( + "About to recover a viewport for existing alignment: Sequence set ID is " + uniqueSeqSetId); Object seqsetobj = retrieveExistingObj(uniqueSeqSetId); if (seqsetobj != null) @@ -3226,14 +3472,14 @@ public class Jalview2XML if (seqsetobj instanceof String) { uniqueSeqSetId = (String) seqsetobj; - System.err - .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is " + System.err.println( + "Recovered extant sequence set ID mapping for ID : New Sequence set ID is " + uniqueSeqSetId); } else { - System.err - .println("Warning : Collision between sequence set ID string and existing jalview object mapping."); + System.err.println( + "Warning : Collision between sequence set ID string and existing jalview object mapping."); } } @@ -3242,8 +3488,8 @@ public class Jalview2XML * indicate that annotation colours are applied across all groups (pre * Jalview 2.8.1 behaviour) */ - boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan( - "2.8.1", object.getVersion()); + boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan("2.8.1", + object.getVersion()); AlignmentPanel ap = null; boolean isnewview = true; @@ -3318,15 +3564,15 @@ public class Jalview2XML for (int i = 0; i < jseq.getRnaViewerCount(); i++) { RnaViewer viewer = jseq.getRnaViewer(i); - AppVarna appVarna = findOrCreateVarnaViewer(viewer, - uniqueSetSuffix, ap); + AppVarna appVarna = findOrCreateVarnaViewer(viewer, uniqueSetSuffix, + ap); for (int j = 0; j < viewer.getSecondaryStructureCount(); j++) { SecondaryStructure ss = viewer.getSecondaryStructure(j); SequenceI seq = seqRefIds.get(jseq.getId()); - AlignmentAnnotation ann = this.annotationIds.get(ss - .getAnnotationId()); + AlignmentAnnotation ann = this.annotationIds + .get(ss.getAnnotationId()); /* * add the structure to the Varna display (with session state copied @@ -3336,7 +3582,7 @@ public class Jalview2XML String rnaTitle = ss.getTitle(); String sessionState = ss.getViewerState(); String tempStateFile = copyJarEntry(jprovider, sessionState, - "varna"); + "varna", null); RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped); appVarna.addModelSession(rna, rnaTitle, tempStateFile); } @@ -3380,10 +3626,9 @@ public class Jalview2XML /* * viewer not found - make it */ - RnaViewerModel model = new RnaViewerModel(postLoadId, - viewer.getTitle(), viewer.getXpos(), viewer.getYpos(), - viewer.getWidth(), viewer.getHeight(), - viewer.getDividerLocation()); + RnaViewerModel model = new RnaViewerModel(postLoadId, viewer.getTitle(), + viewer.getXpos(), viewer.getYpos(), viewer.getWidth(), + viewer.getHeight(), viewer.getDividerLocation()); AppVarna varna = new AppVarna(model, ap); return varna; @@ -3412,7 +3657,7 @@ public class Jalview2XML TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId()); if (tp == null) { - tp = af.ShowNewickTree( + tp = af.showNewickTree( new jalview.io.NewickFile(tree.getNewick()), tree.getTitle(), tree.getWidth(), tree.getHeight(), tree.getXpos(), tree.getYpos()); @@ -3427,8 +3672,8 @@ public class Jalview2XML // TODO: should check if tp has been manipulated by user - if so its // settings shouldn't be modified tp.setTitle(tree.getTitle()); - tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree - .getWidth(), tree.getHeight())); + tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), + tree.getWidth(), tree.getHeight())); tp.av = av; // af.viewport; // TODO: verify 'associate with all // views' // works still @@ -3448,13 +3693,13 @@ public class Jalview2XML if (tree.getFontName() != null) { - tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree - .getFontStyle(), tree.getFontSize())); + tp.setTreeFont(new java.awt.Font(tree.getFontName(), + tree.getFontStyle(), tree.getFontSize())); } else { - tp.setTreeFont(new java.awt.Font(view.getFontName(), view - .getFontStyle(), tree.getFontSize())); + tp.setTreeFont(new java.awt.Font(view.getFontName(), + view.getFontStyle(), tree.getFontSize())); } tp.showPlaceholders(tree.getMarkUnlinked()); @@ -3490,7 +3735,7 @@ public class Jalview2XML * Run through all PDB ids on the alignment, and collect mappings between * distinct view ids and all sequences referring to that view. */ - Map structureViewers = new LinkedHashMap(); + Map structureViewers = new LinkedHashMap<>(); for (int i = 0; i < jseqs.length; i++) { @@ -3511,7 +3756,8 @@ public class Jalview2XML // Originally : ids[p].getFile() // : TODO: verify external PDB file recovery still works in normal // jalview project load - jpdb.setFile(loadPDBFile(jprovider, ids[p].getId())); + jpdb.setFile(loadPDBFile(jprovider, ids[p].getId(), + ids[p].getFile())); jpdb.setId(ids[p].getId()); int x = structureState.getXpos(); @@ -3522,13 +3768,14 @@ public class Jalview2XML // Probably don't need to do this anymore... // Desktop.desktop.getComponentAt(x, y); // TODO: NOW: check that this recovers the PDB file correctly. - String pdbFile = loadPDBFile(jprovider, ids[p].getId()); - jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i] - .getId() + ""); + String pdbFile = loadPDBFile(jprovider, ids[p].getId(), + ids[p].getFile()); + jalview.datamodel.SequenceI seq = seqRefIds + .get(jseqs[i].getId() + ""); if (sviewid == null) { - sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width - + "," + height; + sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width + "," + + height; } if (!structureViewers.containsKey(sviewid)) { @@ -3547,8 +3794,9 @@ public class Jalview2XML // linkAlignPanel,superposeWithAlignpanel}} from hash StructureViewerModel jmoldat = structureViewers.get(sviewid); jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel() - | (structureState.hasAlignwithAlignPanel() ? structureState - .getAlignwithAlignPanel() : false)); + | (structureState.hasAlignwithAlignPanel() + ? structureState.getAlignwithAlignPanel() + : false)); /* * Default colour by linked panel to false if not specified (e.g. @@ -3556,8 +3804,9 @@ public class Jalview2XML */ boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel(); colourWithAlignPanel |= (structureState - .hasColourwithAlignPanel() ? structureState - .getColourwithAlignPanel() : false); + .hasColourwithAlignPanel() + ? structureState.getColourwithAlignPanel() + : false); jmoldat.setColourWithAlignPanel(colourWithAlignPanel); /* @@ -3565,8 +3814,9 @@ public class Jalview2XML * pre-2.7 projects) */ boolean colourByViewer = jmoldat.isColourByViewer(); - colourByViewer &= structureState.hasColourByJmol() ? structureState - .getColourByJmol() : true; + colourByViewer &= structureState.hasColourByJmol() + ? structureState.getColourByJmol() + : true; jmoldat.setColourByViewer(colourByViewer); if (jmoldat.getStateData().length() < structureState @@ -3582,8 +3832,7 @@ public class Jalview2XML StructureData seqstrmaps = jmoldat.getFileData().get(mapkey); if (seqstrmaps == null) { - jmoldat.getFileData().put( - mapkey, + jmoldat.getFileData().put(mapkey, seqstrmaps = jmoldat.new StructureData(pdbFile, ids[p].getId())); } @@ -3611,8 +3860,8 @@ public class Jalview2XML createOrLinkStructureViewer(entry, af, ap, jprovider); } catch (Exception e) { - System.err.println("Error loading structure viewer: " - + e.getMessage()); + System.err.println( + "Error loading structure viewer: " + e.getMessage()); // failed - try the next one } } @@ -3682,12 +3931,12 @@ public class Jalview2XML */ String viewerJarEntryName = getViewerJarEntryName(data.getViewId()); chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName, - "chimera"); + "chimera", null); Set> fileData = data.getFileData() .entrySet(); - List pdbs = new ArrayList(); - List allseqs = new ArrayList(); + List pdbs = new ArrayList<>(); + List allseqs = new ArrayList<>(); for (Entry pdb : fileData) { String filePath = pdb.getValue().getFilePath(); @@ -3704,8 +3953,8 @@ public class Jalview2XML // TODO use StructureViewer as a factory here, see JAL-1761 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]); - final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs - .size()][]); + final SequenceI[][] seqsArray = allseqs + .toArray(new SequenceI[allseqs.size()][]); String newViewId = viewerData.getKey(); ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile, @@ -3743,9 +3992,9 @@ public class Jalview2XML getViewerJarEntryName(svattrib.getViewId())); } - List pdbfilenames = new ArrayList(); - List seqmaps = new ArrayList(); - List pdbids = new ArrayList(); + List pdbfilenames = new ArrayList<>(); + List seqmaps = new ArrayList<>(); + List pdbids = new ArrayList<>(); StringBuilder newFileLoc = new StringBuilder(64); int cp = 0, ncp, ecp; Map oldFiles = svattrib.getFileData(); @@ -3763,6 +4012,11 @@ public class Jalview2XML // filename // translation differently. StructureData filedat = oldFiles.get(new File(oldfilenam)); + if (filedat == null) + { + String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\"); + filedat = oldFiles.get(new File(reformatedOldFilename)); + } newFileLoc.append(Platform.escapeString(filedat.getFilePath())); pdbfilenames.add(filedat.getFilePath()); pdbids.add(filedat.getPdbId()); @@ -3811,8 +4065,8 @@ public class Jalview2XML */ histbug += 10; int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug); - String val = (diff == -1) ? null : newFileLoc - .substring(histbug, diff); + String val = (diff == -1) ? null + : newFileLoc.substring(histbug, diff); if (val != null && val.length() >= 4) { if (val.contains("e")) // eh? what can it be? @@ -3830,8 +4084,8 @@ public class Jalview2XML } } - final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames - .size()]); + final String[] pdbf = pdbfilenames + .toArray(new String[pdbfilenames.size()]); final String[] id = pdbids.toArray(new String[pdbids.size()]); final SequenceI[][] sq = seqmaps .toArray(new SequenceI[seqmaps.size()][]); @@ -3850,10 +4104,11 @@ public class Jalview2XML JalviewStructureDisplayI sview = null; try { - sview = new StructureViewer(alf.alignPanel - .getStructureSelectionManager()).createView( - StructureViewer.ViewerType.JMOL, pdbf, id, sq, - alf.alignPanel, svattrib, fileloc, rect, sviewid); + sview = new StructureViewer( + alf.alignPanel.getStructureSelectionManager()) + .createView(StructureViewer.ViewerType.JMOL, + pdbf, id, sq, alf.alignPanel, svattrib, + fileloc, rect, sviewid); addNewStructureViewer(sview); } catch (OutOfMemoryError ex) { @@ -3913,9 +4168,8 @@ public class Jalview2XML /* * Post jalview 2.4 schema includes structure view id */ - if (sviewid != null - && ((StructureViewerBase) frame).getViewId() - .equals(sviewid)) + if (sviewid != null && ((StructureViewerBase) frame).getViewId() + .equals(sviewid)) { comp = (StructureViewerBase) frame; break; // break added in 2.9 @@ -3968,8 +4222,8 @@ public class Jalview2XML StructureData filedat = oldFiles.get(id); String pdbFile = filedat.getFilePath(); SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]); - binding.getSsm().setMapping(seq, null, pdbFile, - jalview.io.AppletFormatAdapter.FILE); + binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE, + null); binding.addSequenceForStructFile(pdbFile, seq); } // and add the AlignmentPanel's reference to the view panel @@ -4021,18 +4275,22 @@ public class Jalview2XML } /** + * Answers true if 'version' is equal to or later than 'supported', where each + * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix + * changes. Development and test values for 'version' are leniently treated + * i.e. answer true. * * @param supported * - minimum version we are comparing against * @param version - * - version of data being processsed. - * @return true if version is development/null or evaluates to the same or - * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*) + * - version of data being processsed + * @return */ public static boolean isVersionStringLaterThan(String supported, String version) { - if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD") + if (supported == null || version == null + || version.equalsIgnoreCase("DEVELOPMENT BUILD") || version.equalsIgnoreCase("Test") || version.equalsIgnoreCase("AUTOMATED BUILD")) { @@ -4043,45 +4301,8 @@ public class Jalview2XML } else { - StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer( - version, "."); - while (currentV.hasMoreTokens() && fileV.hasMoreTokens()) - { - // convert b to decimal to catch bugfix releases within a series - String curT = currentV.nextToken().toLowerCase().replace('b', '.'); - String fileT = fileV.nextToken().toLowerCase().replace('b', '.'); - try - { - float supportedVersionToken = Float.parseFloat(curT); - float myVersiontoken = Float.parseFloat(fileT); - if (supportedVersionToken > myVersiontoken) - { - // current version is newer than the version that wrote the file - return false; - } - if (supportedVersionToken < myVersiontoken) - { - // current version is older than the version that wrote the file - return true; - } - } catch (NumberFormatException nfe) - { - System.err - .println("** WARNING: Version comparison failed for tokens (" - + curT - + ") and (" - + fileT - + ")\n** Current: '" - + supported + "' and Version: '" + version + "'"); - } - } - if (currentV.hasMoreElements()) - { - // fileV has no minor version but identical series to current - return false; - } + return StringUtils.compareVersions(version, supported, "b") >= 0; } - return true; } Vector newStructureViewers = null; @@ -4109,7 +4330,7 @@ public class Jalview2XML } AlignFrame loadViewport(String file, JSeq[] JSEQ, - List hiddenSeqs, Alignment al, + List hiddenSeqs, AlignmentI al, JalviewModelSequence jms, Viewport view, String uniqueSeqSetId, String viewId, List autoAlan) { @@ -4117,12 +4338,19 @@ public class Jalview2XML af = new AlignFrame(al, view.getWidth(), view.getHeight(), uniqueSeqSetId, viewId); - af.setFileName(file, "Jalview"); + af.setFileName(file, FileFormat.Jalview); for (int i = 0; i < JSEQ.length; i++) { - af.viewport.setSequenceColour(af.viewport.getAlignment() - .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour())); + af.viewport.setSequenceColour( + af.viewport.getAlignment().getSequenceAt(i), + new java.awt.Color(JSEQ[i].getColour())); + } + + if (al.hasSeqrep()) + { + af.getViewport().setColourByReferenceSeq(true); + af.getViewport().setDisplayReferenceSeq(true); } af.viewport.setGatherViewsHere(view.getGatheredViews()); @@ -4151,50 +4379,44 @@ public class Jalview2XML { for (int s = 0; s < JSEQ.length; s++) { - jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup(); - + SequenceGroup hidden = new SequenceGroup(); + boolean isRepresentative = false; for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++) { - hidden.addSequence( - al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false); + isRepresentative = true; + SequenceI sequenceToHide = al + .getSequenceAt(JSEQ[s].getHiddenSequences(r)); + hidden.addSequence(sequenceToHide, false); + // remove from hiddenSeqs list so we don't try to hide it twice + hiddenSeqs.remove(sequenceToHide); + } + if (isRepresentative) + { + SequenceI representativeSequence = al.getSequenceAt(s); + hidden.addSequence(representativeSequence, false); + af.viewport.hideRepSequences(representativeSequence, hidden); } - af.viewport.hideRepSequences(al.getSequenceAt(s), hidden); } - // jalview.datamodel.SequenceI[] hseqs = new - // jalview.datamodel.SequenceI[hiddenSeqs - // .size()]; - // - // for (int s = 0; s < hiddenSeqs.size(); s++) - // { - // hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s); - // } - - SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs - .size()]); + SequenceI[] hseqs = hiddenSeqs + .toArray(new SequenceI[hiddenSeqs.size()]); af.viewport.hideSequence(hseqs); } // recover view properties and display parameters - if (view.getViewName() != null) - { - af.viewport.viewName = view.getViewName(); - af.setInitialTabVisible(); - } - af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(), - view.getHeight()); af.viewport.setShowAnnotation(view.getShowAnnotation()); af.viewport.setAbovePIDThreshold(view.getPidSelected()); + af.viewport.setThreshold(view.getPidThreshold()); af.viewport.setColourText(view.getShowColourText()); af.viewport.setConservationSelected(view.getConservationSelected()); + af.viewport.setIncrement(view.getConsThreshold()); af.viewport.setShowJVSuffix(view.getShowFullId()); af.viewport.setRightAlignIds(view.getRightAlignIds()); - af.viewport.setFont( - new java.awt.Font(view.getFontName(), view.getFontStyle(), view - .getFontSize()), true); + af.viewport.setFont(new java.awt.Font(view.getFontName(), + view.getFontStyle(), view.getFontSize()), true); ViewStyleI vs = af.viewport.getViewStyle(); vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna()); af.viewport.setViewStyle(vs); @@ -4211,10 +4433,18 @@ public class Jalview2XML af.viewport.setTextColour(new java.awt.Color(view.getTextCol1())); af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2())); af.viewport.setThresholdTextColour(view.getTextColThreshold()); - af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view - .isShowUnconserved() : false); - af.viewport.setStartRes(view.getStartRes()); - af.viewport.setStartSeq(view.getStartSeq()); + af.viewport.setShowUnconserved( + view.hasShowUnconserved() ? view.isShowUnconserved() : false); + af.viewport.getRanges().setStartRes(view.getStartRes()); + + if (view.getViewName() != null) + { + af.viewport.viewName = view.getViewName(); + af.setInitialTabVisible(); + } + af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(), + view.getHeight()); + // startSeq set in af.alignPanel.updateLayout below af.alignPanel.updateLayout(); ColourSchemeI cs = null; // apply colourschemes @@ -4234,22 +4464,21 @@ public class Jalview2XML } else { - cs = ColourSchemeProperty.getColour(al, view.getBgColour()); - } - - if (cs != null) - { - cs.setThreshold(view.getPidThreshold(), true); - cs.setConsensus(af.viewport.getSequenceConsensusHash()); + cs = ColourSchemeProperty.getColourScheme(al, view.getBgColour()); } } af.viewport.setGlobalColourScheme(cs); + af.viewport.getResidueShading().setThreshold(view.getPidThreshold(), + view.getIgnoreGapsinConsensus()); + af.viewport.getResidueShading() + .setConsensus(af.viewport.getSequenceConsensusHash()); af.viewport.setColourAppliesToAllGroups(false); if (view.getConservationSelected() && cs != null) { - cs.setConservationInc(view.getConsThreshold()); + af.viewport.getResidueShading() + .setConservationInc(view.getConsThreshold()); } af.changeColour(cs); @@ -4277,8 +4506,8 @@ public class Jalview2XML } if (view.hasShowConsensusHistogram()) { - af.viewport.setShowConsensusHistogram(view - .getShowConsensusHistogram()); + af.viewport + .setShowConsensusHistogram(view.getShowConsensusHistogram()); } else { @@ -4328,25 +4557,34 @@ public class Jalview2XML af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed()); String[] renderOrder = new String[jms.getFeatureSettings() .getSettingCount()]; - Hashtable featureGroups = new Hashtable(); - Hashtable featureColours = new Hashtable(); - Hashtable featureOrder = new Hashtable(); + Map featureColours = new Hashtable<>(); + Map featureOrder = new Hashtable<>(); - for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++) + for (int fs = 0; fs < jms.getFeatureSettings() + .getSettingCount(); fs++) { Setting setting = jms.getFeatureSettings().getSetting(fs); if (setting.hasMincolour()) { - GraduatedColor gc = setting.hasMin() ? new GraduatedColor( - new java.awt.Color(setting.getMincolour()), - new java.awt.Color(setting.getColour()), - setting.getMin(), setting.getMax()) : new GraduatedColor( - new java.awt.Color(setting.getMincolour()), - new java.awt.Color(setting.getColour()), 0, 1); + FeatureColourI gc = setting.hasMin() + ? new FeatureColour(new Color(setting.getMincolour()), + new Color(setting.getColour()), setting.getMin(), + setting.getMax()) + : new FeatureColour(new Color(setting.getMincolour()), + new Color(setting.getColour()), 0, 1); if (setting.hasThreshold()) { - gc.setThresh(setting.getThreshold()); - gc.setThreshType(setting.getThreshstate()); + gc.setThreshold(setting.getThreshold()); + int threshstate = setting.getThreshstate(); + // -1 = None, 0 = Below, 1 = Above threshold + if (threshstate == 0) + { + gc.setBelowThreshold(true); + } + else if (threshstate == 1) + { + gc.setAboveThreshold(true); + } } gc.setAutoScaled(true); // default if (setting.hasAutoScale()) @@ -4363,7 +4601,7 @@ public class Jalview2XML else { featureColours.put(setting.getType(), - new java.awt.Color(setting.getColour())); + new FeatureColour(new Color(setting.getColour()))); } renderOrder[fs] = setting.getType(); if (setting.hasOrder()) @@ -4372,15 +4610,15 @@ public class Jalview2XML } else { - featureOrder.put(setting.getType(), new Float(fs - / jms.getFeatureSettings().getSettingCount())); + featureOrder.put(setting.getType(), new Float( + fs / jms.getFeatureSettings().getSettingCount())); } if (setting.getDisplay()) { fdi.setVisible(setting.getType()); } } - Hashtable fgtable = new Hashtable(); + Map fgtable = new Hashtable<>(); for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++) { Group grp = jms.getFeatureSettings().getGroup(gs); @@ -4389,8 +4627,8 @@ public class Jalview2XML // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder, // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ? // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder); - FeatureRendererSettings frs = new FeatureRendererSettings( - renderOrder, fgtable, featureColours, 1.0f, featureOrder); + FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder, + fgtable, featureColours, 1.0f, featureOrder); af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer() .transferSettings(frs); @@ -4400,9 +4638,9 @@ public class Jalview2XML { for (int c = 0; c < view.getHiddenColumnsCount(); c++) { - af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view - .getHiddenColumns(c).getEnd() // +1 - ); + af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), + view.getHiddenColumns(c).getEnd() // +1 + ); } } if (view.getCalcIdParam() != null) @@ -4423,7 +4661,7 @@ public class Jalview2XML } } af.setMenusFromViewport(af.viewport); - + af.setTitle(view.getTitle()); // TODO: we don't need to do this if the viewport is aready visible. /* * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it @@ -4447,12 +4685,21 @@ public class Jalview2XML return af; } + /** + * Reads saved data to restore Colour by Annotation settings + * + * @param viewAnnColour + * @param af + * @param al + * @param jms + * @param checkGroupAnnColour + * @return + */ private ColourSchemeI constructAnnotationColour( - AnnotationColours viewAnnColour, AlignFrame af, Alignment al, + AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al, JalviewModelSequence jms, boolean checkGroupAnnColour) { boolean propagateAnnColour = false; - ColourSchemeI cs = null; AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al; if (checkGroupAnnColour && al.getGroups() != null && al.getGroups().size() > 0) @@ -4460,119 +4707,99 @@ public class Jalview2XML // pre 2.8.1 behaviour // check to see if we should transfer annotation colours propagateAnnColour = true; - for (jalview.datamodel.SequenceGroup sg : al.getGroups()) + for (SequenceGroup sg : al.getGroups()) { - if (sg.cs instanceof AnnotationColourGradient) + if (sg.getColourScheme() instanceof AnnotationColourGradient) { propagateAnnColour = false; } } } - // int find annotation - if (annAlignment.getAlignmentAnnotation() != null) + + /* + * 2.10.2- : saved annotationId is AlignmentAnnotation.annotationId + */ + String annotationId = viewAnnColour.getAnnotation(); + AlignmentAnnotation matchedAnnotation = annotationIds.get(annotationId); + + /* + * pre 2.10.2: saved annotationId is AlignmentAnnotation.label + */ + if (matchedAnnotation == null + && annAlignment.getAlignmentAnnotation() != null) { for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++) { - if (annAlignment.getAlignmentAnnotation()[i].label - .equals(viewAnnColour.getAnnotation())) + if (annotationId + .equals(annAlignment.getAlignmentAnnotation()[i].label)) { - if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null) - { - annAlignment.getAlignmentAnnotation()[i] - .setThreshold(new jalview.datamodel.GraphLine( - viewAnnColour.getThreshold(), "Threshold", - java.awt.Color.black) - - ); - } - - if (viewAnnColour.getColourScheme().equals("None")) - { - cs = new AnnotationColourGradient( - annAlignment.getAlignmentAnnotation()[i], - new java.awt.Color(viewAnnColour.getMinColour()), - new java.awt.Color(viewAnnColour.getMaxColour()), - viewAnnColour.getAboveThreshold()); - } - else if (viewAnnColour.getColourScheme().startsWith("ucs")) - { - cs = new AnnotationColourGradient( - annAlignment.getAlignmentAnnotation()[i], - getUserColourScheme(jms, - viewAnnColour.getColourScheme()), - viewAnnColour.getAboveThreshold()); - } - else - { - cs = new AnnotationColourGradient( - annAlignment.getAlignmentAnnotation()[i], - ColourSchemeProperty.getColour(al, - viewAnnColour.getColourScheme()), - viewAnnColour.getAboveThreshold()); - } - if (viewAnnColour.hasPerSequence()) - { - ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour - .isPerSequence()); - } - if (viewAnnColour.hasPredefinedColours()) - { - ((AnnotationColourGradient) cs) - .setPredefinedColours(viewAnnColour - .isPredefinedColours()); - } - if (propagateAnnColour && al.getGroups() != null) - { - // Also use these settings for all the groups - for (int g = 0; g < al.getGroups().size(); g++) - { - jalview.datamodel.SequenceGroup sg = al.getGroups().get(g); - - if (sg.cs == null) - { - continue; - } + matchedAnnotation = annAlignment.getAlignmentAnnotation()[i]; + break; + } + } + } + if (matchedAnnotation == null) + { + System.err.println("Failed to match annotation colour scheme for " + + annotationId); + return null; + } + if (matchedAnnotation.getThreshold() == null) + { + matchedAnnotation.setThreshold(new GraphLine( + viewAnnColour.getThreshold(), "Threshold", Color.black)); + } - /* - * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs = - * new AnnotationColourGradient( - * annAlignment.getAlignmentAnnotation()[i], new - * java.awt.Color(viewAnnColour. getMinColour()), new - * java.awt.Color(viewAnnColour. getMaxColour()), - * viewAnnColour.getAboveThreshold()); } else - */ - { - sg.cs = new AnnotationColourGradient( - annAlignment.getAlignmentAnnotation()[i], sg.cs, - viewAnnColour.getAboveThreshold()); - if (cs instanceof AnnotationColourGradient) - { - if (viewAnnColour.hasPerSequence()) - { - ((AnnotationColourGradient) cs) - .setSeqAssociated(viewAnnColour.isPerSequence()); - } - if (viewAnnColour.hasPredefinedColours()) - { - ((AnnotationColourGradient) cs) - .setPredefinedColours(viewAnnColour - .isPredefinedColours()); - } - } - } + AnnotationColourGradient cs = null; + if (viewAnnColour.getColourScheme().equals("None")) + { + cs = new AnnotationColourGradient(matchedAnnotation, + new Color(viewAnnColour.getMinColour()), + new Color(viewAnnColour.getMaxColour()), + viewAnnColour.getAboveThreshold()); + } + else if (viewAnnColour.getColourScheme().startsWith("ucs")) + { + cs = new AnnotationColourGradient(matchedAnnotation, + getUserColourScheme(jms, viewAnnColour.getColourScheme()), + viewAnnColour.getAboveThreshold()); + } + else + { + cs = new AnnotationColourGradient(matchedAnnotation, + ColourSchemeProperty.getColourScheme(al, + viewAnnColour.getColourScheme()), + viewAnnColour.getAboveThreshold()); + } - } - } + boolean perSequenceOnly = viewAnnColour.isPerSequence(); + boolean useOriginalColours = viewAnnColour.isPredefinedColours(); + cs.setSeqAssociated(perSequenceOnly); + cs.setPredefinedColours(useOriginalColours); - break; + if (propagateAnnColour && al.getGroups() != null) + { + // Also use these settings for all the groups + for (int g = 0; g < al.getGroups().size(); g++) + { + SequenceGroup sg = al.getGroups().get(g); + if (sg.getGroupColourScheme() == null) + { + continue; } + AnnotationColourGradient groupScheme = new AnnotationColourGradient( + matchedAnnotation, sg.getColourScheme(), + viewAnnColour.getAboveThreshold()); + sg.setColourScheme(groupScheme); + groupScheme.setSeqAssociated(perSequenceOnly); + groupScheme.setPredefinedColours(useOriginalColours); } } return cs; } - private void reorderAutoannotation(AlignFrame af, Alignment al, + private void reorderAutoannotation(AlignFrame af, AlignmentI al, List autoAlan) { // copy over visualization settings for autocalculated annotation in the @@ -4585,7 +4812,7 @@ public class Jalview2XML String[] magicNames = new String[] { "Consensus", "Quality", "Conservation" }; JvAnnotRow nullAnnot = new JvAnnotRow(-1, null); - Hashtable visan = new Hashtable(); + Hashtable visan = new Hashtable<>(); for (String nm : magicNames) { visan.put(nm, nullAnnot); @@ -4593,15 +4820,16 @@ public class Jalview2XML for (JvAnnotRow auan : autoAlan) { visan.put(auan.template.label - + (auan.template.getCalcId() == null ? "" : "\t" - + auan.template.getCalcId()), auan); + + (auan.template.getCalcId() == null ? "" + : "\t" + auan.template.getCalcId()), + auan); } int hSize = al.getAlignmentAnnotation().length; - List reorder = new ArrayList(); + List reorder = new ArrayList<>(); // work through any autoCalculated annotation already on the view // removing it if it should be placed in a different location on the // annotation panel. - List remains = new ArrayList(visan.keySet()); + List remains = new ArrayList<>(visan.keySet()); for (int h = 0; h < hSize; h++) { jalview.datamodel.AlignmentAnnotation jalan = al @@ -4697,8 +4925,9 @@ public class Jalview2XML return false; } String id; - if (skipList.containsKey(id = object.getJalviewModelSequence() - .getViewport()[0].getSequenceSetId())) + if (skipList.containsKey( + id = object.getJalviewModelSequence().getViewport()[0] + .getSequenceSetId())) { if (Cache.log != null && Cache.log.isDebugEnabled()) { @@ -4727,10 +4956,11 @@ public class Jalview2XML } } - private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al, + private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al, boolean ignoreUnrefed) { - jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId()); + jalview.datamodel.AlignmentI ds = getDatasetFor( + vamsasSet.getDatasetId()); Vector dseqs = null; if (ds == null) { @@ -4740,7 +4970,7 @@ public class Jalview2XML for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++) { Sequence vamsasSeq = vamsasSet.getSequence(i); - ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed); + ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i); } // create a new dataset if (ds == null) @@ -4767,18 +4997,29 @@ public class Jalview2XML * dataset alignment * @param dseqs * vector to add new dataset sequence to + * @param ignoreUnrefed + * - when true, don't create new sequences from vamsasSeq if it's id + * doesn't already have an asssociated Jalview sequence. + * @param vseqpos + * - used to reorder the sequence in the alignment according to the + * vamsasSeq array ordering, to preserve ordering of dataset */ private void ensureJalviewDatasetSequence(Sequence vamsasSeq, - AlignmentI ds, Vector dseqs, boolean ignoreUnrefed) + AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos) { // JBP TODO: Check this is called for AlCodonFrames to support recovery of // xRef Codon Maps SequenceI sq = seqRefIds.get(vamsasSeq.getId()); + boolean reorder = false; SequenceI dsq = null; if (sq != null && sq.getDatasetSequence() != null) { dsq = sq.getDatasetSequence(); } + else + { + reorder = true; + } if (sq == null && ignoreUnrefed) { return; @@ -4868,27 +5109,56 @@ public class Jalview2XML } // TODO: merges will never happen if we 'know' we have the real dataset // sequence - this should be detected when id==dssid - System.err - .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // (" + System.err.println( + "DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // (" // + (pre ? "prepended" : "") + " " // + (post ? "appended" : "")); } } + else + { + // sequence refs are identical. We may need to update the existing dataset + // alignment with this one, though. + if (ds != null && dseqs == null) + { + int opos = ds.findIndex(dsq); + SequenceI tseq = null; + if (opos != -1 && vseqpos != opos) + { + // remove from old position + ds.deleteSequence(dsq); + } + if (vseqpos < ds.getHeight()) + { + if (vseqpos != opos) + { + // save sequence at destination position + tseq = ds.getSequenceAt(vseqpos); + ds.replaceSequenceAt(vseqpos, dsq); + ds.addSequence(tseq); + } + } + else + { + ds.addSequence(dsq); + } + } + } } /* * TODO use AlignmentI here and in related methods - needs * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment */ - Hashtable datasetIds = null; + Hashtable datasetIds = null; - IdentityHashMap dataset2Ids = null; + IdentityHashMap dataset2Ids = null; - private Alignment getDatasetFor(String datasetId) + private AlignmentI getDatasetFor(String datasetId) { if (datasetIds == null) { - datasetIds = new Hashtable(); + datasetIds = new Hashtable<>(); return null; } if (datasetIds.containsKey(datasetId)) @@ -4898,11 +5168,11 @@ public class Jalview2XML return null; } - private void addDatasetRef(String datasetId, Alignment dataset) + private void addDatasetRef(String datasetId, AlignmentI dataset) { if (datasetIds == null) { - datasetIds = new Hashtable(); + datasetIds = new Hashtable<>(); } datasetIds.put(datasetId, dataset); } @@ -4913,7 +5183,7 @@ public class Jalview2XML * @param dataset * @return */ - private String getDatasetIdRef(Alignment dataset) + private String getDatasetIdRef(AlignmentI dataset) { if (dataset.getDataset() != null) { @@ -4925,7 +5195,7 @@ public class Jalview2XML // make a new datasetId and record it if (dataset2Ids == null) { - dataset2Ids = new IdentityHashMap(); + dataset2Ids = new IdentityHashMap<>(); } else { @@ -4946,8 +5216,9 @@ public class Jalview2XML { DBRef dr = sequence.getDBRef(d); jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry( - sequence.getDBRef(d).getSource(), sequence.getDBRef(d) - .getVersion(), sequence.getDBRef(d).getAccessionId()); + sequence.getDBRef(d).getSource(), + sequence.getDBRef(d).getVersion(), + sequence.getDBRef(d).getAccessionId()); if (dr.getMapping() != null) { entry.setMap(addMapping(dr.getMapping())); @@ -4976,8 +5247,8 @@ public class Jalview2XML fto[_i] = mf.getStart(); fto[_i + 1] = mf.getEnd(); } - jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto, - fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit()); + jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto, fr, + fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit()); if (m.getMappingChoice() != null) { MappingChoice mc = m.getMappingChoice(); @@ -4993,7 +5264,7 @@ public class Jalview2XML } else { - frefedSequence.add(new Object[] { dsfor, jmap }); + frefedSequence.add(newMappingRef(dsfor, jmap)); } } else @@ -5013,8 +5284,8 @@ public class Jalview2XML } else { - System.err - .println("Warning - making up dataset sequence id for DbRef sequence map reference"); + System.err.println( + "Warning - making up dataset sequence id for DbRef sequence map reference"); sqid = ((Object) ms).toString(); // make up a new hascode for // undefined dataset sequence hash // (unlikely to happen) @@ -5031,6 +5302,7 @@ public class Jalview2XML djs.setEnd(jmap.getMap().getToHighest()); djs.setVamsasId(uniqueSetSuffix + sqid); jmap.setTo(djs); + incompleteSeqs.put(sqid, djs); seqRefIds.put(sqid, djs); } @@ -5043,28 +5315,25 @@ public class Jalview2XML } - public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap, - boolean keepSeqRefs) + /** + * Provides a 'copy' of an alignment view (on action New View) by 'saving' the + * view as XML (but not to file), and then reloading it + * + * @param ap + * @return + */ + public AlignmentPanel copyAlignPanel(AlignmentPanel ap) { initSeqRefs(); JalviewModel jm = saveState(ap, null, null, null); - if (!keepSeqRefs) - { - clearSeqRefs(); - jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null); - } - else - { - uniqueSetSuffix = ""; - jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't - // overwrite the - // view we just - // copied - } + uniqueSetSuffix = ""; + jm.getJalviewModelSequence().getViewport(0).setId(null); + // we don't overwrite the view we just copied + if (this.frefedSequence == null) { - frefedSequence = new Vector(); + frefedSequence = new Vector(); } viewportsAdded.clear(); @@ -5084,32 +5353,8 @@ public class Jalview2XML return af.alignPanel; } - /** - * flag indicating if hashtables should be cleared on finalization TODO this - * flag may not be necessary - */ - private final boolean _cleartables = true; - private Hashtable jvids2vobj; - /* - * (non-Javadoc) - * - * @see java.lang.Object#finalize() - */ - @Override - protected void finalize() throws Throwable - { - // really make sure we have no buried refs left. - if (_cleartables) - { - clearSeqRefs(); - } - this.seqRefIds = null; - this.seqsToIds = null; - super.finalize(); - } - private void warn(String msg) { warn(msg, null); @@ -5203,11 +5448,11 @@ public class Jalview2XML // register sequence object so the XML parser can recover it. if (seqRefIds == null) { - seqRefIds = new HashMap(); + seqRefIds = new HashMap<>(); } if (seqsToIds == null) { - seqsToIds = new IdentityHashMap(); + seqsToIds = new IdentityHashMap<>(); } seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj); seqsToIds.put((SequenceI) jvobj, id);