From eb83cb0287f1598b1ba8538b78836377fc05984f Mon Sep 17 00:00:00 2001 From: hansonr Date: Tue, 2 Jul 2019 14:30:50 +0200 Subject: [PATCH] JAL-3253 Jalview2XML minor recoding; suggesting InvokeLater rather than InvokeAndWait to allow some asynchronous updating --- src/jalview/project/Jalview2XML.java | 216 ++++++++++++++++++++++++++-------- 1 file changed, 164 insertions(+), 52 deletions(-) diff --git a/src/jalview/project/Jalview2XML.java b/src/jalview/project/Jalview2XML.java index 4ad61d9..22d7bfd 100644 --- a/src/jalview/project/Jalview2XML.java +++ b/src/jalview/project/Jalview2XML.java @@ -28,6 +28,7 @@ import jalview.analysis.Conservation; import jalview.analysis.PCA; import jalview.analysis.scoremodels.ScoreModels; import jalview.analysis.scoremodels.SimilarityParams; +import jalview.api.AlignmentViewPanel; import jalview.api.FeatureColourI; import jalview.api.ViewStyleI; import jalview.api.analysis.ScoreModelI; @@ -162,7 +163,6 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; -import java.lang.reflect.InvocationTargetException; import java.math.BigInteger; import java.net.MalformedURLException; import java.net.URL; @@ -623,13 +623,14 @@ public class Jalview2XML * core method for storing state for a set of AlignFrames. * * @param frames - * - frames involving all data to be exported (including containing - * splitframes) + * - frames involving all data to be exported (including those + * contained in splitframes, though not the split frames themselves) * @param jout * - project output stream */ private void saveAllFrames(List frames, JarOutputStream jout) { + Hashtable dsses = new Hashtable<>(); /* @@ -652,21 +653,22 @@ public class Jalview2XML for (int i = frames.size() - 1; i > -1; i--) { AlignFrame af = frames.get(i); + AlignViewport vp = af.getViewport(); // skip ? if (skipList != null && skipList - .containsKey(af.getViewport().getSequenceSetId())) + .containsKey(vp.getSequenceSetId())) { continue; } String shortName = makeFilename(af, shortNames); - int apSize = af.getAlignPanels().size(); - + AlignmentI alignment = vp.getAlignment(); + List panels = af.getAlignPanels(); + int apSize = panels.size(); for (int ap = 0; ap < apSize; ap++) - { - AlignmentPanel apanel = (AlignmentPanel) af.getAlignPanels() - .get(ap); + { + AlignmentPanel apanel = (AlignmentPanel) panels.get(ap); String fileName = apSize == 1 ? shortName : ap + shortName; if (!fileName.endsWith(".xml")) { @@ -674,11 +676,17 @@ public class Jalview2XML } saveState(apanel, fileName, jout, viewIds); - - String dssid = getDatasetIdRef( - af.getViewport().getAlignment().getDataset()); + } + if (apSize > 0) + { + // BH moved next bit out of inner loop, not that it really matters. + // so we are testing to make sure we actually have an alignment, + // apparently. + String dssid = getDatasetIdRef(alignment.getDataset()); if (!dsses.containsKey(dssid)) { + // We have not already covered this data by reference from another + // frame. dsses.put(dssid, af); } } @@ -796,12 +804,21 @@ public class Jalview2XML } } + /** + * Each AlignFrame has a single data set associated with it. Note that none of + * these frames are split frames, because Desktop.getAlignFrames() collects + * top and bottom separately here. + * + * @param dsses + * @param fileName + * @param jout + */ private void writeDatasetFor(Hashtable dsses, String fileName, JarOutputStream jout) { - // BH: Question: What is this Dataset for, as it seems to - // duplicate the actual XML file data. + // Note that in saveAllFrames we have associated each specific dataset to + // ONE of its associated frames. for (String dssids : dsses.keySet()) { @@ -2757,7 +2774,8 @@ public class Jalview2XML { try { - SwingUtilities.invokeAndWait(new Runnable() + // BH 2019 -- can't wait + SwingUtilities.invokeLater(new Runnable() { @Override public void run() @@ -2850,6 +2868,9 @@ public class Jalview2XML JarEntry jarentry = null; int entryCount = 1; + // Look for all the entry names ending with ".xml" + // This includes all panels and at least one frame. +// Platform.timeCheck(null, Platform.TIME_MARK); do { jin = jprovider.getJarInputStream(); @@ -2858,14 +2879,21 @@ public class Jalview2XML jarentry = jin.getNextJarEntry(); } String name = (jarentry == null ? null : jarentry.getName()); - if (name != null && name.endsWith(".xml") - // The question here is what to do with the two - // .xml files in the jvp file. They are identical? - // && name.indexOf(" Dataset for ") < 0 // BH 2019.05.21 - // we need to talk about how to avoid the full duplication of - // reading these. - ) + if (name != null && name.endsWith(".xml")) { + + // The question here is what to do with the two + // .xml files in the jvp file. + // Some number of them, "...Dataset for...", will be the + // Only AlignPanels and will have Viewport. + // One or more will be the source data, with the DBRefs. + // + // JVP file writing (above) ensures tha the AlignPanels are written + // first, then all relevant datasets (which are + // Jalview.datamodel.Alignment). + // + +// Platform.timeCheck("Jalview2XML JAXB " + name, Platform.TIME_MARK); JAXBContext jc = JAXBContext .newInstance("jalview.xml.binding.jalview"); XMLStreamReader streamReader = XMLInputFactory.newInstance() @@ -2873,14 +2901,19 @@ public class Jalview2XML javax.xml.bind.Unmarshaller um = jc.createUnmarshaller(); JAXBElement jbe = um .unmarshal(streamReader, JalviewModel.class); - JalviewModel object = jbe.getValue(); + JalviewModel model = jbe.getValue(); if (true) // !skipViewport(object)) { - _af = loadFromObject(object, file, true, jprovider); - if (_af != null && object.getViewport().size() > 0) - // getJalviewModelSequence().getViewportCount() > 0) + // Q: Do we have to load from the model, even if it + // does not have a viewport, could we discover that early on? + // Q: Do we need to load this object? + _af = loadFromObject(model, file, true, jprovider); +// Platform.timeCheck("Jalview2XML.loadFromObject", + // Platform.TIME_MARK); + if (_af != null && model.getViewport().size() > 0) { + // That is, this is one of the AlignmentPanel models if (af == null) { // store a reference to the first view @@ -2900,6 +2933,7 @@ public class Jalview2XML af.getViewport().getAlignment().getDataset()); } } +// Platform.timeCheck("JAXB " + name, Platform.TIME_MARK); entryCount++; } else if (jarentry != null) @@ -2908,7 +2942,10 @@ public class Jalview2XML entryCount++; } } while (jarentry != null); +// Platform.timeCheck("JAXB loop exit", Platform.TIME_MARK); resolveFrefedSequences(); +// Platform.timeCheck("JAXB resolveFrefed", Platform.TIME_MARK); + } catch (IOException ex) { ex.printStackTrace(); @@ -3271,7 +3308,9 @@ public class Jalview2XML } /** - * Load alignment frame from jalview XML DOM object + * Load alignment frame from jalview XML DOM object. For a DOM object that + * includes one or more Viewport elements (one with a title that does NOT + * contain "Dataset for"), create the frame. * * @param jalviewModel * DOM @@ -3286,9 +3325,13 @@ public class Jalview2XML AlignFrame loadFromObject(JalviewModel jalviewModel, String file, boolean loadTreesAndStructures, jarInputStreamProvider jprovider) { + +// Platform.timeCheck("Jalview2XML.loadFromObject0", Platform.TIME_MARK); + SequenceSet vamsasSet = jalviewModel.getVamsasModel().getSequenceSet().get(0); List vamsasSeqs = vamsasSet.getSequence(); + // JalviewModelSequence jms = object.getJalviewModelSequence(); // Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0) @@ -3319,6 +3362,7 @@ public class Jalview2XML : view.getId() + uniqueSetSuffix); } +// Platform.timeCheck("Jalview2XML.loadFromObject1", Platform.TIME_MARK); // //////////////////////////////// // LOAD SEQUENCES @@ -3339,6 +3383,7 @@ public class Jalview2XML SequenceI tmpSeq = seqRefIds.get(seqId); if (tmpSeq != null) { + // if (!incompleteSeqs.containsKey(seqId)) { // may not need this check, but keep it for at least 2.9,1 release @@ -3403,6 +3448,8 @@ public class Jalview2XML } } +// Platform.timeCheck("Jalview2XML.loadFromObject-seq", +// Platform.TIME_MARK); // / // Create the alignment object from the sequence set // /////////////////////////////// @@ -3443,6 +3490,8 @@ public class Jalview2XML recoverDatasetFor(vamsasSet, al, isdsal, uniqueSeqSetId); } +// Platform.timeCheck("Jalview2XML.loadFromObject-align", +// Platform.TIME_MARK); if (referenceseqForView != null) { al.setSeqrep(referenceseqForView); @@ -3455,6 +3504,8 @@ public class Jalview2XML al.setProperty(ssp.getKey(), ssp.getValue()); } +// Platform.timeCheck("Jalview2XML.loadFromObject-setseqprop", +// Platform.TIME_MARK); // /////////////////////////////// Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this?? @@ -3596,6 +3647,8 @@ public class Jalview2XML } } } +// Platform.timeCheck("Jalview2XML.loadFromObject-endmultiview", +// Platform.TIME_MARK); } // end !multipleview // /////////////////////////////// @@ -3637,6 +3690,8 @@ public class Jalview2XML al.addCodonFrame(cf); } } +// Platform.timeCheck("Jalview2XML.loadFromObject-seqmap", +// Platform.TIME_MARK); } // //////////////////////////////// @@ -3697,6 +3752,9 @@ public class Jalview2XML } // Construct new annotation from model. List ae = annotation.getAnnotationElement(); +// System.err.println( +// "Jalview2XML processing " + ae.size() + " annotations"); + jalview.datamodel.Annotation[] anot = null; java.awt.Color firstColour = null; int anpos; @@ -3732,6 +3790,7 @@ public class Jalview2XML } } } + // create the new AlignmentAnnotation jalview.datamodel.AlignmentAnnotation jaa = null; if (annotation.isGraph()) @@ -3768,6 +3827,7 @@ public class Jalview2XML jaa._linecolour = firstColour; } // register new annotation + // Annotation graphs such as Conservation will not have id. if (annotation.getId() != null) { annotationIds.put(annotation.getId(), jaa); @@ -3856,6 +3916,8 @@ public class Jalview2XML al.addAnnotation(jaa); } } +// Platform.timeCheck("Jalview2XML.loadFromObject-annot", +// Platform.TIME_MARK); } // /////////////////////// // LOAD GROUPS @@ -3970,6 +4032,8 @@ public class Jalview2XML jGroup.getAnnotationColours(), null, al, jalviewModel, false)); } } +// Platform.timeCheck("Jalview2XML.loadFromObject-groups", +// Platform.TIME_MARK); } if (view == null) { @@ -3979,8 +4043,6 @@ public class Jalview2XML // /////////////////////////////// // LOAD VIEWPORT - AlignFrame af = null; - AlignViewport av = null; // now check to see if we really need to create a new viewport. if (multipleView && viewportsAdded.size() == 0) { @@ -4011,6 +4073,8 @@ public class Jalview2XML } } +// Platform.timeCheck("Jalview2XML.loadFromObject-viewport", +// Platform.TIME_MARK); } /** * indicate that annotation colours are applied across all groups (pre @@ -4019,8 +4083,9 @@ public class Jalview2XML boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan("2.8.1", jalviewModel.getVersion()); + AlignFrame af = null; AlignmentPanel ap = null; - boolean isnewview = true; + AlignViewport av = null; if (viewId != null) { // Check to see if this alignment already has a view id == viewId @@ -4030,25 +4095,27 @@ public class Jalview2XML { for (int v = 0; v < views.length; v++) { - if (views[v].av.getViewId().equalsIgnoreCase(viewId)) + ap = views[v]; + av = ap.av; + if (av.getViewId().equalsIgnoreCase(viewId)) { // recover the existing alignpanel, alignframe, viewport - af = views[v].alignFrame; - av = views[v].av; - ap = views[v]; + af = ap.alignFrame; + break; // TODO: could even skip resetting view settings if we don't want to // change the local settings from other jalview processes - isnewview = false; } } } } - if (isnewview) + if (af == null) { af = loadViewport(file, jseqs, hiddenSeqs, al, jalviewModel, view, uniqueSeqSetId, viewId, autoAlan); av = af.getViewport(); + // note that this only retrieves the most recently accessed + // tab of an AlignFrame. ap = af.alignPanel; } @@ -4057,12 +4124,57 @@ public class Jalview2XML * * Not done if flag is false (when this method is used for New View) */ + final AlignFrame af0 = af; + final AlignViewport av0 = av; + final AlignmentPanel ap0 = ap; +// Platform.timeCheck("Jalview2XML.loadFromObject-beforetree", +// Platform.TIME_MARK); if (loadTreesAndStructures) { - loadTrees(jalviewModel, view, af, av, ap); - loadPCAViewers(jalviewModel, ap); - loadPDBStructures(jprovider, jseqs, af, ap); - loadRnaViewers(jprovider, jseqs, ap); + if (!jalviewModel.getTree().isEmpty()) + { + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { +// Platform.timeCheck(null, Platform.TIME_MARK); + loadTrees(jalviewModel, view, af0, av0, ap0); +// Platform.timeCheck("Jalview2XML.loadTrees", Platform.TIME_MARK); + } + }); + } + if (!jalviewModel.getPcaViewer().isEmpty()) + { + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { +// Platform.timeCheck(null, Platform.TIME_MARK); + loadPCAViewers(jalviewModel, ap0); +// Platform.timeCheck("Jalview2XML.loadPCA", Platform.TIME_MARK); + } + }); + } + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { +// Platform.timeCheck(null, Platform.TIME_MARK); + loadPDBStructures(jprovider, jseqs, af0, ap0); +// Platform.timeCheck("Jalview2XML.loadPDB", Platform.TIME_MARK); + } + }); + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { + loadRnaViewers(jprovider, jseqs, ap0); + } + }); } // and finally return. return af; @@ -4081,7 +4193,7 @@ public class Jalview2XML * @param jseqs * @param ap */ - private void loadRnaViewers(jarInputStreamProvider jprovider, + protected void loadRnaViewers(jarInputStreamProvider jprovider, List jseqs, AlignmentPanel ap) { /* @@ -4619,9 +4731,9 @@ public class Jalview2XML final AlignFrame alf = af; final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(), svattrib.getWidth(), svattrib.getHeight()); - try - { - javax.swing.SwingUtilities.invokeAndWait(new Runnable() + // try + // { + javax.swing.SwingUtilities.invokeLater(new Runnable() { @Override public void run() @@ -4648,14 +4760,14 @@ public class Jalview2XML } } }); - } catch (InvocationTargetException ex) - { - warn("Unexpected error when opening Jmol view.", ex); - - } catch (InterruptedException e) - { - // e.printStackTrace(); - } + // } catch (InvocationTargetException ex) + // { + // warn("Unexpected error when opening Jmol view.", ex); + // + // } catch (InterruptedException e) + // { + // // e.printStackTrace(); + // } } -- 1.7.10.2