X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fproject%2FJalview2XML.java;h=983b5121d23243e530d136fafe5add9aab156bc4;hb=a9177efb4097815d9a8031aa22700c61a7d6260a;hp=af3b2c8e4ba5df144d5452c4c53bc17092895ec1;hpb=b8ee563aafbad9f5a0812cd1f5588ee8e9055570;p=jalview.git diff --git a/src/jalview/project/Jalview2XML.java b/src/jalview/project/Jalview2XML.java index af3b2c8..983b512 100644 --- a/src/jalview/project/Jalview2XML.java +++ b/src/jalview/project/Jalview2XML.java @@ -91,12 +91,15 @@ import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; +import jalview.datamodel.ContactListI; import jalview.datamodel.ContactMatrix; import jalview.datamodel.ContactMatrixI; import jalview.datamodel.DBRefEntry; +import jalview.datamodel.FloatContactMatrix; import jalview.datamodel.GeneLocus; import jalview.datamodel.GraphLine; import jalview.datamodel.GroupSet; +import jalview.datamodel.GroupSetI; import jalview.datamodel.PDBEntry; import jalview.datamodel.Point; import jalview.datamodel.RnaViewerModel; @@ -199,6 +202,7 @@ import jalview.xml.binding.jalview.JalviewUserColours.Colour; import jalview.xml.binding.jalview.MapListType; import jalview.xml.binding.jalview.MapListType.MapListFrom; import jalview.xml.binding.jalview.MapListType.MapListTo; +import jalview.xml.binding.jalview.MapOnAMatrixType; import jalview.xml.binding.jalview.Mapping; import jalview.xml.binding.jalview.MatrixType; import jalview.xml.binding.jalview.NoValueColour; @@ -268,7 +272,7 @@ public class Jalview2XML Map incompleteSeqs = null; - List frefedSequence = null; + List frefedSequence = null; boolean raiseGUI = true; // whether errors are raised in dialog boxes or not @@ -285,6 +289,15 @@ public class Jalview2XML private Map rnaSessions = new HashMap<>(); /** + * map from contact matrices to their XML ids + */ + private Map contactMatrices = new HashMap<>(); + + private Map contactMatrixRefs = new HashMap<>(); + + private List xmlMatrices = new ArrayList<>(); + + /** * A helper method for safely using the value of an optional attribute that * may be null if not present in the XML. Answers the boolean value, or false * if null. @@ -380,18 +393,19 @@ public class Jalview2XML } /** - * base class for resolving forward references to sequences by their ID + * base class for resolving forward references to an as-yet unmarshalled + * object referenced by already unmarshalled objects * * @author jprocter * */ - abstract class SeqFref + abstract class forwardRef { String sref; String type; - public SeqFref(String _sref, String type) + public forwardRef(String _sref, String type) { sref = _sref; this.type = type; @@ -402,6 +416,32 @@ public class Jalview2XML return sref; } + public abstract boolean isResolvable(); + + /** + * @return true if the forward reference was fully resolved + */ + abstract boolean resolve(); + + @Override + public String toString() + { + return type + " reference to " + sref; + } + } + + /** + * resolve forward references to sequences by their ID + * + * @author jprocter + */ + abstract class SeqFref extends forwardRef + { + public SeqFref(String _sref, String type) + { + super(_sref, type); + } + public SequenceI getSrefSeq() { return seqRefIds.get(sref); @@ -424,17 +464,6 @@ public class Jalview2XML } return sq; } - - /** - * @return true if the forward reference was fully resolved - */ - abstract boolean resolve(); - - @Override - public String toString() - { - return type + " reference to " + sref; - } } /** @@ -498,14 +527,41 @@ public class Jalview2XML return fref; } + public forwardRef newMatrixFref(final String matRef, + final jalview.util.MapList mapping, final AlignmentAnnotation jaa) + { + forwardRef fref = new forwardRef(matRef, + "Matrix Reference for sequence and annotation") + { + + @Override + boolean resolve() + { + ContactMatrixI cm = contactMatrixRefs.get(matRef); + PAEContactMatrix newpae = new PAEContactMatrix(jaa.sequenceRef, + mapping, cm); + + jaa.sequenceRef.addContactListFor(jaa, newpae); + return true; + } + + @Override + public boolean isResolvable() + { + return (contactMatrixRefs.get(matRef) != null); + } + }; + return fref; + } + public void resolveFrefedSequences() { - Iterator nextFref = frefedSequence.iterator(); + Iterator nextFref = frefedSequence.iterator(); int toresolve = frefedSequence.size(); int unresolved = 0, failedtoresolve = 0; while (nextFref.hasNext()) { - SeqFref ref = nextFref.next(); + forwardRef ref = nextFref.next(); if (ref.isResolvable()) { try @@ -631,7 +687,7 @@ public class Jalview2XML */ public void saveState(JarOutputStream jout) { - AlignFrame[] frames = Desktop.getAlignFrames(); + AlignFrame[] frames = Desktop.getDesktopAlignFrames(); setStateSavedUpToDate(true); @@ -1598,6 +1654,10 @@ public class Jalview2XML view.setShowColourText(av.getColourText()); view.setShowFullId(av.getShowJVSuffix()); view.setRightAlignIds(av.isRightAlignIds()); + view.setIdWidth(av.getIdWidth()); + view.setIdWidthManuallyAdjusted( + ap.getIdPanel().getIdCanvas().isManuallyAdjusted()); + view.setShowSequenceFeatures(av.isShowSequenceFeatures()); view.setShowText(av.getShowText()); view.setShowUnconserved(av.getShowUnconserved()); @@ -1769,6 +1829,19 @@ public class Jalview2XML // jms.addViewport(view); object.getViewport().add(view); } + + if (storeDS) + { + // store matrices referenced by any views or annotation in this dataset + if (xmlMatrices != null && xmlMatrices.size() > 0) + { + Console.debug( + "Adding " + xmlMatrices.size() + " matrices to dataset."); + vamsasSet.getMatrix().addAll(xmlMatrices); + xmlMatrices.clear(); + } + } + // object.setJalviewModelSequence(jms); // object.getVamsasModel().addSequenceSet(vamsasSet); object.getVamsasModel().getSequenceSet().add(vamsasSet); @@ -2333,64 +2406,7 @@ public class Jalview2XML .getContactMatrixFor(annotation); if (cm != null) { - MatrixType xmlmat = new MatrixType(); - xmlmat.setType(cm.getType()); - xmlmat.setRows(BigInteger.valueOf(cm.getWidth())); - xmlmat.setCols(BigInteger.valueOf(cm.getHeight())); - // consider using an opaque to/from -> allow instance to control - // its representation ? - xmlmat.setElements(ContactMatrix.contactToFloatString(cm)); - if (cm.hasGroups()) - { - for (BitSet gp : cm.getGroups()) - { - xmlmat.getGroups().add(stringifyBitset(gp)); - } - } - if (cm.hasTree()) - { - // provenance object for tree ? - xmlmat.getNewick().add(cm.getNewick()); - xmlmat.setTreeMethod(cm.getTreeMethod()); - } - if (cm.hasCutHeight()) - { - xmlmat.setCutHeight(cm.getCutHeight()); - } - // set/get properties - if (cm instanceof MappableContactMatrixI) - { - jalview.util.MapList mlst = ((MappableContactMatrixI) cm) - .getMapFor(annotation.sequenceRef); - if (mlst != null) - { - MapListType mp = new MapListType(); - List r = mlst.getFromRanges(); - for (int[] range : r) - { - MapListFrom mfrom = new MapListFrom(); - mfrom.setStart(range[0]); - mfrom.setEnd(range[1]); - // mp.addMapListFrom(mfrom); - mp.getMapListFrom().add(mfrom); - } - r = mlst.getToRanges(); - for (int[] range : r) - { - MapListTo mto = new MapListTo(); - mto.setStart(range[0]); - mto.setEnd(range[1]); - // mp.addMapListTo(mto); - mp.getMapListTo().add(mto); - } - mp.setMapFromUnit( - BigInteger.valueOf(mlst.getFromRatio())); - mp.setMapToUnit(BigInteger.valueOf(mlst.getToRatio())); - xmlmat.setMapping(mp); - } - } - // and add to model - an.getContactmatrix().add(xmlmat); + storeMatrixFor(vamsasSet, an, annotation, cm); } } } @@ -2497,6 +2513,92 @@ public class Jalview2XML } + private void storeMatrixFor(SequenceSet root, Annotation an, + AlignmentAnnotation annotation, ContactMatrixI cm) + { + String cmId = contactMatrices.get(cm); + MatrixType xmlmat = null; + + // first create an xml ref for the matrix data, if none exist + if (cmId == null) + { + xmlmat = new MatrixType(); + xmlmat.setType(cm.getType()); + xmlmat.setRows(BigInteger.valueOf(cm.getWidth())); + xmlmat.setCols(BigInteger.valueOf(cm.getHeight())); + // consider using an opaque to/from -> allow instance to control + // its representation ? + xmlmat.setElements(ContactMatrix.contactToFloatString(cm)); + if (cm.hasGroups()) + { + for (BitSet gp : cm.getGroups()) + { + xmlmat.getGroups().add(stringifyBitset(gp)); + } + } + if (cm.hasTree()) + { + // provenance object for tree ? + xmlmat.getNewick().add(cm.getNewick()); + xmlmat.setTreeMethod(cm.getTreeMethod()); + } + if (cm.hasCutHeight()) + { + xmlmat.setCutHeight(cm.getCutHeight()); + } + xmlmat.setId(cmId = "m" + contactMatrices.size() + + System.currentTimeMillis()); + Console.trace("Matrix data stored :" + cmId); + contactMatrices.put(cm, cmId); + contactMatrixRefs.put(cmId, cm); + xmlMatrices.add(xmlmat); + } + else + { + Console.trace("Existing Matrix stored :" + cmId); + } + + // now store mapping + + MapOnAMatrixType xmlmatmapping = new MapOnAMatrixType(); + xmlmatmapping.setMatrix(cmId); + + // Pretty much all matrices currently managed in this way are + // mappableContactMatrixI implementations - but check anyway + if (cm instanceof MappableContactMatrixI) + { + jalview.util.MapList mlst = ((MappableContactMatrixI) cm) + .getMapFor(annotation.sequenceRef); + if (mlst != null) + { + MapListType mp = new MapListType(); + List r = mlst.getFromRanges(); + for (int[] range : r) + { + MapListFrom mfrom = new MapListFrom(); + mfrom.setStart(range[0]); + mfrom.setEnd(range[1]); + // mp.addMapListFrom(mfrom); + mp.getMapListFrom().add(mfrom); + } + r = mlst.getToRanges(); + for (int[] range : r) + { + MapListTo mto = new MapListTo(); + mto.setStart(range[0]); + mto.setEnd(range[1]); + // mp.addMapListTo(mto); + mp.getMapListTo().add(mto); + } + mp.setMapFromUnit(BigInteger.valueOf(mlst.getFromRatio())); + mp.setMapToUnit(BigInteger.valueOf(mlst.getToRatio())); + xmlmatmapping.setMapping(mp); + } + } + // and add to model + an.getContactmatrix().add(xmlmatmapping); + } + private String stringifyBitset(BitSet gp) { StringBuilder sb = new StringBuilder(); @@ -3073,6 +3175,7 @@ public class Jalview2XML initSeqRefs(); } AlignFrame af = null, _af = null; + List toRepaint = new ArrayList(); IdentityHashMap importedDatasets = new IdentityHashMap<>(); Map gatherToThisFrame = new HashMap<>(); final String file = jprovider.getFilename(); @@ -3107,6 +3210,7 @@ public class Jalview2XML if (_af != null && object.getViewport().size() > 0) // getJalviewModelSequence().getViewportCount() > 0) { + toRepaint.add(_af); if (af == null) { // store a reference to the first view @@ -3136,6 +3240,10 @@ public class Jalview2XML } while (jarentry != null); jin.close(); resolveFrefedSequences(); + for (AlignFrame alignFrame : toRepaint) + { + alignFrame.repaint(); + } } catch (IOException ex) { ex.printStackTrace(); @@ -3526,6 +3634,14 @@ public class Jalview2XML } // //////////////////////////////// + // LOAD MATRICES (IF ANY) + + if (vamsasSet.getMatrix() != null && vamsasSet.getMatrix().size() > 0) + { + importMatrixData(vamsasSet.getMatrix()); + } + + // //////////////////////////////// // LOAD SEQUENCES List hiddenSeqs = null; @@ -4057,79 +4173,9 @@ public class Jalview2XML if (annotation.getContactmatrix() != null && annotation.getContactmatrix().size() > 0) { - for (MatrixType xmlmat : annotation.getContactmatrix()) + for (MapOnAMatrixType xmlmat : annotation.getContactmatrix()) { - if (PAEContactMatrix.PAEMATRIX.equals(xmlmat.getType())) - { - if (!xmlmat.getRows().equals(xmlmat.getCols())) - { - Console.error("Can't handle non square PAE Matrices"); - } - else - { - float[][] elements = ContactMatrix - .fromFloatStringToContacts(xmlmat.getElements(), - xmlmat.getCols().intValue(), - xmlmat.getRows().intValue()); - jalview.util.MapList mapping = null; - if (xmlmat.getMapping() != null) - { - MapListType m = xmlmat.getMapping(); - // Mapping m = dr.getMapping(); - int fr[] = new int[m.getMapListFrom().size() * 2]; - Iterator from = m.getMapListFrom() - .iterator();// enumerateMapListFrom(); - for (int _i = 0; from.hasNext(); _i += 2) - { - MapListFrom mf = from.next(); - fr[_i] = mf.getStart(); - fr[_i + 1] = mf.getEnd(); - } - int fto[] = new int[m.getMapListTo().size() * 2]; - Iterator to = m.getMapListTo().iterator();// enumerateMapListTo(); - for (int _i = 0; to.hasNext(); _i += 2) - { - MapListTo mf = to.next(); - fto[_i] = mf.getStart(); - fto[_i + 1] = mf.getEnd(); - } - - mapping = new jalview.util.MapList(fr, fto, - m.getMapFromUnit().intValue(), - m.getMapToUnit().intValue()); - } - List newgroups = new ArrayList(); - if (xmlmat.getGroups().size() > 0) - { - for (String sgroup : xmlmat.getGroups()) - { - newgroups.add(deStringifyBitset(sgroup)); - } - } - String nwk = xmlmat.getNewick().size() > 0 - ? xmlmat.getNewick().get(0) - : null; - if (xmlmat.getNewick().size() > 1) - { - Console.log.info( - "Ignoring additional clusterings for contact matrix"); - } - String treeMethod = xmlmat.getTreeMethod(); - double thresh = xmlmat.getCutHeight() != null - ? xmlmat.getCutHeight() - : 0; - GroupSet grpset = new GroupSet(); - grpset.restoreGroups(newgroups, treeMethod, nwk, thresh); - PAEContactMatrix newpae = new PAEContactMatrix( - jaa.sequenceRef, mapping, elements, grpset); - jaa.sequenceRef.addContactListFor(jaa, newpae); - } - } - else - { - Console.error("Ignoring CONTACT_MAP annotation with type " - + xmlmat.getType()); - } + restoreMatrixFor(jaa.sequenceRef, jaa, xmlmat); } } } @@ -4360,6 +4406,103 @@ public class Jalview2XML return af; } + private void importMatrixData(List xmlmatrices) + { + for (MatrixType xmlmat : xmlmatrices) + { + if (!PAEContactMatrix.PAEMATRIX.equals(xmlmat.getType())) + { + Console.error("Ignoring matrix '" + xmlmat.getId() + "' of type '" + + xmlmat.getType()); + continue; + } + + if (!xmlmat.getRows().equals(xmlmat.getCols())) + { + Console.error("Can't handle non square matrices"); + continue; + } + + float[][] elements = ContactMatrix.fromFloatStringToContacts( + xmlmat.getElements(), xmlmat.getCols().intValue(), + xmlmat.getRows().intValue()); + + List newgroups = new ArrayList(); + if (xmlmat.getGroups().size() > 0) + { + for (String sgroup : xmlmat.getGroups()) + { + newgroups.add(deStringifyBitset(sgroup)); + } + } + String nwk = xmlmat.getNewick().size() > 0 ? xmlmat.getNewick().get(0) + : null; + if (xmlmat.getNewick().size() > 1) + { + Console.log + .info("Ignoring additional clusterings for contact matrix"); + } + String treeMethod = xmlmat.getTreeMethod(); + double thresh = xmlmat.getCutHeight() != null ? xmlmat.getCutHeight() + : 0; + GroupSet grpset = new GroupSet(); + grpset.restoreGroups(newgroups, treeMethod, nwk, thresh); + + FloatContactMatrix newcm = new FloatContactMatrix(elements, grpset); + contactMatrixRefs.put(xmlmat.getId(), newcm); + Console.trace("Restored base contact matrix " + xmlmat.getId()); + } + } + + private void restoreMatrixFor(SequenceI sequenceRef, + AlignmentAnnotation jaa, MapOnAMatrixType xmlmatmapping) + { + // restore mapping data to matrix data + jalview.util.MapList mapping = null; + if (xmlmatmapping.getMapping() != null) + { + MapListType m = xmlmatmapping.getMapping(); + // Mapping m = dr.getMapping(); + int fr[] = new int[m.getMapListFrom().size() * 2]; + Iterator from = m.getMapListFrom().iterator();// enumerateMapListFrom(); + for (int _i = 0; from.hasNext(); _i += 2) + { + MapListFrom mf = from.next(); + fr[_i] = mf.getStart(); + fr[_i + 1] = mf.getEnd(); + } + int fto[] = new int[m.getMapListTo().size() * 2]; + Iterator to = m.getMapListTo().iterator();// enumerateMapListTo(); + for (int _i = 0; to.hasNext(); _i += 2) + { + MapListTo mf = to.next(); + fto[_i] = mf.getStart(); + fto[_i + 1] = mf.getEnd(); + } + + mapping = new jalview.util.MapList(fr, fto, + m.getMapFromUnit().intValue(), m.getMapToUnit().intValue()); + } + + // locate matrix data in project XML and import + ContactMatrixI cm = contactMatrixRefs.get(xmlmatmapping.getMatrix()); + if (cm == null) + { + frefedSequence + .add(newMatrixFref(xmlmatmapping.getMatrix(), mapping, jaa)); + } + else + { + // create the PAEMatrix now + PAEContactMatrix newpae = new PAEContactMatrix(jaa.sequenceRef, + mapping, cm); + + jaa.sequenceRef.addContactListFor(jaa, newpae); + } + + return; + } + /** * Load Overview window, restoring colours, 'show hidden regions' flag, title * and geometry as saved @@ -5111,6 +5254,26 @@ public class Jalview2XML } af.setBounds(safeInt(view.getXpos()), safeInt(view.getYpos()), safeInt(view.getWidth()), safeInt(view.getHeight())); + + af.alignPanel.fontChanged(); // make sure font is updated *before* we set ID + // width + if (view.getIdWidth() == null) + { + if (!isVersionStringLaterThan("2.11.3", jm.getVersion())) + { + // Pre 2.11.3 jalview projects do not store the id width + // idWidth was also calculated in a different way. + viewport.setIdWidth(af.alignPanel.getLegacyIdWidth()); + af.alignPanel.getIdPanel().getIdCanvas().setManuallyAdjusted(true); + } + } + else + { + viewport.setIdWidth(view.getIdWidth()); + af.alignPanel.getIdPanel().getIdCanvas() + .setManuallyAdjusted(view.isIdWidthManuallyAdjusted()); + } + // startSeq set in af.alignPanel.updateLayout below af.alignPanel.updateLayout(); ColourSchemeI cs = null; @@ -6919,7 +7082,7 @@ public class Jalview2XML if (stateSavedUpToDate()) // nothing happened since last project save return true; - AlignFrame[] frames = Desktop.getAlignFrames(); + AlignFrame[] frames = Desktop.getDesktopAlignFrames(); if (frames != null) { for (int i = 0; i < frames.length; i++)