X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fproject%2FJalview2XML.java;h=e88a4a183238c6e0f2ef974aadc3e781e0f933d0;hb=7d602d0e4b439e56af3e4551ed71f181a8025534;hp=4d772a18de6c6936d2297cd7ee160ade1f1dface;hpb=cc6197585bf74c9562c0b869a4d28646af5b13bc;p=jalview.git diff --git a/src/jalview/project/Jalview2XML.java b/src/jalview/project/Jalview2XML.java index 4d772a1..e88a4a1 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; @@ -39,7 +40,9 @@ import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.DBRefEntry; +import jalview.datamodel.GeneLocus; import jalview.datamodel.GraphLine; +import jalview.datamodel.HiddenMarkovModel; import jalview.datamodel.PDBEntry; import jalview.datamodel.Point; import jalview.datamodel.RnaViewerModel; @@ -72,6 +75,7 @@ import jalview.gui.TreePanel; import jalview.io.BackupFiles; import jalview.io.DataSourceType; import jalview.io.FileFormat; +import jalview.io.HMMFile; import jalview.io.NewickFile; import jalview.math.Matrix; import jalview.math.MatrixI; @@ -82,7 +86,6 @@ import jalview.schemes.ColourSchemeProperty; import jalview.schemes.FeatureColour; import jalview.schemes.ResidueProperties; import jalview.schemes.UserColourScheme; -import jalview.structure.StructureSelectionManager; import jalview.structures.models.AAStructureBindingModel; import jalview.util.Format; import jalview.util.MessageManager; @@ -93,11 +96,12 @@ import jalview.util.matcher.Condition; import jalview.viewmodel.AlignmentViewport; import jalview.viewmodel.PCAModel; import jalview.viewmodel.ViewportRanges; +import jalview.viewmodel.seqfeatures.FeatureRendererModel; import jalview.viewmodel.seqfeatures.FeatureRendererSettings; import jalview.viewmodel.seqfeatures.FeaturesDisplayed; -import jalview.ws.jws2.Jws2Discoverer; +import jalview.ws.api.ServiceWithParameters; +import jalview.ws.jws2.PreferredServiceRegistry; import jalview.ws.jws2.dm.AAConSettings; -import jalview.ws.jws2.jabaws2.Jws2Instance; import jalview.ws.params.ArgumentI; import jalview.ws.params.AutoCalcSetting; import jalview.ws.params.WsParamSetI; @@ -150,6 +154,7 @@ import jalview.xml.binding.jalview.ThresholdType; import jalview.xml.binding.jalview.VAMSAS; import java.awt.Color; +import java.awt.Dimension; import java.awt.Font; import java.awt.Rectangle; import java.io.BufferedReader; @@ -160,10 +165,10 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; 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; @@ -223,6 +228,8 @@ public class Jalview2XML private static final String RNA_PREFIX = "rna_"; + private static final String HMMER_PREFIX = "hmmer_"; + private static final String UTF_8 = "UTF-8"; /** @@ -266,6 +273,25 @@ public class Jalview2XML private Map rnaSessions = new HashMap<>(); /** + * contains last error message (if any) encountered by XML loader. + */ + String errorMessage = null; + + /** + * flag to control whether the Jalview2XML_V1 parser should be deferred to if + * exceptions are raised during project XML parsing + */ + public boolean attemptversion1parse = false; + + /* + * JalviewJS only -- to allow read file bytes to be saved in the + * created AlignFrame, allowing File | Reload of a project file to work + * + * BH 2019 JAL-3436 + */ + private File jarFile; + + /** * 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. @@ -425,7 +451,7 @@ public class Jalview2XML * @param _jmap * @return */ - public SeqFref newMappingRef(final String sref, + protected SeqFref newMappingRef(final String sref, final jalview.datamodel.Mapping _jmap) { SeqFref fref = new SeqFref(sref, "Mapping") @@ -447,7 +473,7 @@ public class Jalview2XML return fref; } - public SeqFref newAlcodMapRef(final String sref, + protected SeqFref newAlcodMapRef(final String sref, final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap) { @@ -479,7 +505,7 @@ public class Jalview2XML return fref; } - public void resolveFrefedSequences() + protected void resolveFrefedSequences() { Iterator nextFref = frefedSequence.iterator(); int toresolve = frefedSequence.size(); @@ -624,13 +650,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<>(); /* @@ -653,21 +680,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")) { @@ -675,11 +703,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); } } @@ -797,10 +831,22 @@ 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) { + // Note that in saveAllFrames we have associated each specific dataset to + // ONE of its associated frames. + for (String dssids : dsses.keySet()) { AlignFrame _af = dsses.get(dssids); @@ -827,7 +873,7 @@ public class Jalview2XML * @param out * jar entry name */ - public JalviewModel saveState(AlignmentPanel ap, String fileName, + protected JalviewModel saveState(AlignmentPanel ap, String fileName, JarOutputStream jout, List viewIds) { return saveState(ap, fileName, false, jout, viewIds); @@ -849,7 +895,7 @@ public class Jalview2XML * @param out * jar entry name */ - public JalviewModel saveState(AlignmentPanel ap, String fileName, + protected JalviewModel saveState(AlignmentPanel ap, String fileName, boolean storeDS, JarOutputStream jout, List viewIds) { if (viewIds == null) @@ -1063,6 +1109,9 @@ public class Jalview2XML jseq.getFeatures().add(features); } + /* + * save PDB entries for sequence + */ if (jdatasq.getAllPDBEntries() != null) { Enumeration en = jdatasq.getAllPDBEntries().elements(); @@ -1081,7 +1130,7 @@ public class Jalview2XML * only view *should* be coped with sensibly. */ // This must have been loaded, is it still visible? - JInternalFrame[] frames = Desktop.desktop.getAllFrames(); + JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames(); String matchedFile = null; for (int f = frames.length - 1; f > -1; f--) { @@ -1155,6 +1204,11 @@ public class Jalview2XML saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS); + if (jds.hasHMMProfile()) + { + saveHmmerProfile(jout, jseq, jds); + } + // jms.addJSeq(jseq); object.getJSeq().add(jseq); } @@ -1233,9 +1287,9 @@ public class Jalview2XML { // FIND ANY ASSOCIATED TREES // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT - if (Desktop.desktop != null) + if (Desktop.getDesktopPane() != null) { - JInternalFrame[] frames = Desktop.desktop.getAllFrames(); + JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames(); for (int t = 0; t < frames.length; t++) { @@ -1279,9 +1333,9 @@ public class Jalview2XML /* * save PCA viewers */ - if (!storeDS && Desktop.desktop != null) + if (!storeDS && Desktop.getDesktopPane() != null) { - for (JInternalFrame frame : Desktop.desktop.getAllFrames()) + for (JInternalFrame frame : Desktop.getDesktopPane().getAllFrames()) { if (frame instanceof PCAPanel) { @@ -1512,11 +1566,14 @@ public class Jalview2XML view.setFollowHighlight(av.isFollowHighlight()); view.setFollowSelection(av.followSelection); view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus()); + view.setShowComplementFeatures(av.isShowComplementFeatures()); + view.setShowComplementFeaturesOnTop( + av.isShowComplementFeaturesOnTop()); if (av.getFeaturesDisplayed() != null) { FeatureSettings fs = new FeatureSettings(); - FeatureRenderer fr = ap.getSeqPanel().seqCanvas + FeatureRendererModel fr = ap.getSeqPanel().seqCanvas .getFeatureRenderer(); String[] renderOrder = fr.getRenderOrder().toArray(new String[0]); @@ -1700,7 +1757,39 @@ public class Jalview2XML } return object; } + /** + * Saves the HMMER profile associated with the sequence as a file in the jar, + * in HMMER format, and saves the name of the file as a child element of the + * XML sequence element + * + * @param jout + * @param xmlSeq + * @param seq + */ + protected void saveHmmerProfile(JarOutputStream jout, JSeq xmlSeq, + SequenceI seq) + { + HiddenMarkovModel profile = seq.getHMM(); + if (profile == null) + { + warn("Want to save HMM profile for " + seq.getName() + + " but none found"); + return; + } + HMMFile hmmFile = new HMMFile(profile); + String hmmAsString = hmmFile.print(); + String jarEntryName = HMMER_PREFIX + nextCounter(); + try + { + writeJarEntry(jout, jarEntryName, hmmAsString.getBytes()); + xmlSeq.setHmmerProfile(jarEntryName); + } catch (IOException e) + { + warn("Error saving HMM profile: " + e.getMessage()); + } + } + /** * Writes PCA viewer attributes and computed values to an XML model object and * adds it to the JalviewModel. Any exceptions are reported by logging. @@ -1919,11 +2008,11 @@ public class Jalview2XML final SequenceI jds, List viewIds, AlignmentPanel ap, boolean storeDataset) { - if (Desktop.desktop == null) + if (Desktop.getDesktopPane() == null) { return; } - JInternalFrame[] frames = Desktop.desktop.getAllFrames(); + JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames(); for (int f = frames.length - 1; f > -1; f--) { if (frames[f] instanceof AppVarna) @@ -2095,9 +2184,9 @@ 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): " - + pdbentry.getFile()); + Cache.log.warn( + "Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): " + + pdbentry.getFile()); } // record the // file so we @@ -2379,7 +2468,7 @@ public class Jalview2XML if (calcIdParam.getVersion().equals("1.0")) { final String[] calcIds = calcIdParam.getServiceURL().toArray(new String[0]); - Jws2Instance service = Jws2Discoverer.getDiscoverer() + ServiceWithParameters service = PreferredServiceRegistry.getRegistry() .getPreferredServiceFor(calcIds); if (service != null) { @@ -2412,7 +2501,7 @@ public class Jalview2XML argList = parmSet.getArguments(); parmSet = null; } - AAConSettings settings = new AAConSettings( + AutoCalcSetting settings = new AAConSettings( calcIdParam.isAutoUpdate(), service, parmSet, argList); av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings, calcIdParam.isNeedsUpdate()); @@ -2420,7 +2509,7 @@ public class Jalview2XML } else { - warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server."); + warn("Cannot resolve a service for the parameters used in this project. Try configuring a server in the Web Services preferences tab."); return false; } } @@ -2520,6 +2609,10 @@ public class Jalview2XML parentseq = jds; } } + + /* + * save any dbrefs; special subclass GeneLocus is flagged as 'locus' + */ if (dbrefs != null) { for (int d = 0, nd = dbrefs.size(); d < nd; d++) @@ -2529,13 +2622,16 @@ public class Jalview2XML dbref.setSource(ref.getSource()); dbref.setVersion(ref.getVersion()); dbref.setAccessionId(ref.getAccessionId()); + if (ref instanceof GeneLocus) + { + dbref.setLocus(true); + } if (ref.hasMap()) { Mapping mp = createVamsasMapping(ref.getMap(), parentseq, jds, recurse); dbref.setMapping(mp); } - // vamsasSeq.addDBRef(dbref); vamsasSeq.getDBRef().add(dbref); } } @@ -2711,17 +2807,6 @@ public class Jalview2XML } /** - * contains last error message (if any) encountered by XML loader. - */ - String errorMessage = null; - - /** - * flag to control whether the Jalview2XML_V1 parser should be deferred to if - * exceptions are raised during project XML parsing - */ - public boolean attemptversion1parse = false; - - /** * Load a jalview project archive from a jar file * * @param file @@ -2755,7 +2840,10 @@ public class Jalview2XML { try { - SwingUtilities.invokeAndWait(new Runnable() +// was invokeAndWait + + // BH 2019 -- can't wait + SwingUtilities.invokeLater(new Runnable() { @Override public void run() @@ -2768,55 +2856,61 @@ public class Jalview2XML System.err.println("Error loading alignment: " + x.getMessage()); } } + this.jarFile = null; return af; } @SuppressWarnings("unused") - private jarInputStreamProvider createjarInputStreamProvider(final Object ofile) throws MalformedURLException { - - // BH 2018 allow for bytes already attached to File object - try { - String file = (ofile instanceof File ? ((File) ofile).getCanonicalPath() : ofile.toString()); + private jarInputStreamProvider createjarInputStreamProvider( + final Object ofile) throws MalformedURLException + { + try + { + String file = (ofile instanceof File + ? ((File) ofile).getCanonicalPath() + : ofile.toString()); byte[] bytes = Platform.isJS() ? Platform.getFileBytes((File) ofile) : null; - URL url = null; - errorMessage = null; - uniqueSetSuffix = null; - seqRefIds = null; - viewportsAdded.clear(); - frefedSequence = null; - - if (file.startsWith("http://")) { - url = new URL(file); - } - final URL _url = url; - return new jarInputStreamProvider() { - - @Override - public JarInputStream getJarInputStream() throws IOException { - if (bytes != null) { -// System.out.println("Jalview2XML: opening byte jarInputStream for bytes.length=" + bytes.length); - return new JarInputStream(new ByteArrayInputStream(bytes)); - } - if (_url != null) { -// System.out.println("Jalview2XML: opening url jarInputStream for " + _url); - return new JarInputStream(_url.openStream()); - } else { -// System.out.println("Jalview2XML: opening file jarInputStream for " + file); - return new JarInputStream(new FileInputStream(file)); - } - } - - @Override - public String getFilename() { - return file; - } - }; - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } + if (bytes != null) + { + this.jarFile = (File) ofile; + } + errorMessage = null; + uniqueSetSuffix = null; + seqRefIds = null; + viewportsAdded.clear(); + frefedSequence = null; + + URL url = file.startsWith("http://") ? new URL(file) : null; + return new jarInputStreamProvider() + { + @Override + public JarInputStream getJarInputStream() throws IOException + { + InputStream is = bytes != null ? new ByteArrayInputStream(bytes) + : (url != null ? url.openStream() + : new FileInputStream(file)); + return new JarInputStream(is); + } + + @Override + public File getFile() + { + return jarFile; + } + + @Override + public String getFilename() + { + return file; + } + }; + } catch (IOException e) + { + e.printStackTrace(); + return null; + } + } /** * Recover jalview session from a jalview project archive. Caller may @@ -2841,13 +2935,20 @@ public class Jalview2XML AlignFrame af = null, _af = null; IdentityHashMap importedDatasets = new IdentityHashMap<>(); Map gatherToThisFrame = new HashMap<>(); - final String file = jprovider.getFilename(); + String fileName = jprovider.getFilename(); + File file = jprovider.getFile(); + List alignFrames = new ArrayList<>(); + try { JarInputStream jin = null; 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(); @@ -2855,9 +2956,27 @@ public class Jalview2XML { jarentry = jin.getNextJarEntry(); } + String name = (jarentry == null ? null : jarentry.getName()); - if (jarentry != null && jarentry.getName().endsWith(".xml")) +// System.out.println("Jalview2XML opening " + name); + if (name != null && name.endsWith(".xml")) { + + // DataSet for.... is read last. + + + // 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() @@ -2865,14 +2984,25 @@ 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, fileName, file, true, jprovider); +// Platform.timeCheck("Jalview2XML.loadFromObject", + // Platform.TIME_MARK); + + if (_af != null) + { + alignFrames.add(_af); + } + 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 @@ -2904,7 +3034,7 @@ public class Jalview2XML } catch (IOException ex) { ex.printStackTrace(); - errorMessage = "Couldn't locate Jalview XML file : " + file; + errorMessage = "Couldn't locate Jalview XML file : " + fileName; System.err.println( "Exception whilst loading jalview XML file : " + ex + "\n"); } catch (Exception ex) @@ -2915,9 +3045,9 @@ public class Jalview2XML { // used to attempt to parse as V1 castor-generated xml } - if (Desktop.instance != null) + if (Desktop.getInstance() != null) { - Desktop.instance.stopLoading(); + Desktop.getInstance().stopLoading(); } if (af != null) { @@ -2934,6 +3064,13 @@ public class Jalview2XML errorMessage = "Out of memory loading jalview XML file"; System.err.println("Out of memory whilst loading jalview XML file"); e.printStackTrace(); + } finally + { + for (AlignFrame alf : alignFrames) + { + alf.alignPanel.setHoldRepaint(false); + } + } /* @@ -2945,7 +3082,7 @@ public class Jalview2XML */ for (AlignFrame fr : gatherToThisFrame.values()) { - Desktop.instance.gatherViews(fr); + Desktop.getInstance().gatherViews(fr); } restoreSplitFrames(); @@ -2953,8 +3090,7 @@ public class Jalview2XML { if (ds.getCodonFrames() != null) { - StructureSelectionManager - .getStructureSelectionManager(Desktop.instance) + Desktop.getStructureSelectionManager() .registerMappings(ds.getCodonFrames()); } } @@ -2963,9 +3099,9 @@ public class Jalview2XML reportErrors(); } - if (Desktop.instance != null) + if (Desktop.getInstance() != null) { - Desktop.instance.stopLoading(); + Desktop.getInstance().stopLoading(); } return af; @@ -3046,7 +3182,7 @@ public class Jalview2XML */ for (SplitFrame sf : gatherTo) { - Desktop.instance.gatherViews(sf); + Desktop.getInstance().gatherViews(sf); } splitFrameCandidates.clear(); @@ -3105,7 +3241,7 @@ public class Jalview2XML @Override public void run() { - JvOptionPane.showInternalMessageDialog(Desktop.desktop, + JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(), finalErrorMessage, "Error " + (saving ? "saving" : "loading") + " Jalview file", @@ -3264,24 +3400,28 @@ 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 - * @param file + * @param fileName * filename source string + * @param file * @param loadTreesAndStructures * when false only create Viewport * @param jprovider * data source provider * @return alignment frame created from view stored in DOM */ - AlignFrame loadFromObject(JalviewModel jalviewModel, String file, - boolean loadTreesAndStructures, jarInputStreamProvider jprovider) + AlignFrame loadFromObject(JalviewModel jalviewModel, String fileName, + File file, boolean loadTreesAndStructures, jarInputStreamProvider jprovider) { SequenceSet vamsasSet = jalviewModel.getVamsasModel().getSequenceSet().get(0); List vamsasSeqs = vamsasSet.getSequence(); + // JalviewModelSequence jms = object.getJalviewModelSequence(); // Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0) @@ -3339,8 +3479,10 @@ public class Jalview2XML || tmpSeq.getEnd() != jseq.getEnd()) { System.err.println( - "Warning JAL-2154 regression: updating start/end for sequence " - + tmpSeq.toString() + " to " + jseq); + String.format("Warning JAL-2154 regression: updating start/end for sequence %s from %d/%d to %d/%d", + tmpSeq.getName(), tmpSeq.getStart(), + tmpSeq.getEnd(), jseq.getStart(), + jseq.getEnd())); } } else @@ -3575,8 +3717,7 @@ public class Jalview2XML { entry.setProperty(prop.getName(), prop.getValue()); } - StructureSelectionManager - .getStructureSelectionManager(Desktop.instance) + Desktop.getStructureSelectionManager() .registerPDBEntry(entry); // adds PDBEntry to datasequence's set (since Jalview 2.10) if (al.getSequenceAt(i).getDatasetSequence() != null) @@ -3589,6 +3730,17 @@ public class Jalview2XML } } } + + /* + * load any HMMER profile + */ + // TODO fix this + + String hmmJarFile = jseqs.get(i).getHmmerProfile(); + if (hmmJarFile != null && jprovider != null) + { + loadHmmerProfile(jprovider, hmmJarFile, al.getSequenceAt(i)); + } } } // end !multipleview @@ -3726,6 +3878,7 @@ public class Jalview2XML } } } + // create the new AlignmentAnnotation jalview.datamodel.AlignmentAnnotation jaa = null; if (annotation.isGraph()) @@ -3762,6 +3915,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); @@ -3973,8 +4127,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) { @@ -4013,8 +4165,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 @@ -4024,25 +4177,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, + af = loadViewport(fileName, 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; } @@ -4051,18 +4206,90 @@ 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. + // but do not set holdRepaint true just yet, because this could be the + // initial frame with just its dataset. return af; } /** + * Loads a HMMER profile from a file stored in the project, and associates it + * with the specified sequence + * + * @param jprovider + * @param hmmJarFile + * @param seq + */ + protected void loadHmmerProfile(jarInputStreamProvider jprovider, + String hmmJarFile, SequenceI seq) + { + try + { + String hmmFile = copyJarEntry(jprovider, hmmJarFile, "hmm", null); + HMMFile parser = new HMMFile(hmmFile, DataSourceType.FILE); + HiddenMarkovModel hmmModel = parser.getHMM(); + hmmModel = new HiddenMarkovModel(hmmModel, seq); + seq.setHMM(hmmModel); + } catch (IOException e) + { + warn("Error loading HMM profile for " + seq.getName() + ": " + + e.getMessage()); + } + } + + /** * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna * panel is restored from separate jar entries, two (gapped and trimmed) per * sequence and secondary structure. @@ -4075,7 +4302,7 @@ public class Jalview2XML * @param jseqs * @param ap */ - private void loadRnaViewers(jarInputStreamProvider jprovider, + protected void loadRnaViewers(jarInputStreamProvider jprovider, List jseqs, AlignmentPanel ap) { /* @@ -4185,6 +4412,12 @@ public class Jalview2XML tree.getTitle(), safeInt(tree.getWidth()), safeInt(tree.getHeight()), safeInt(tree.getXpos()), safeInt(tree.getYpos())); + if (tp == null) + { + warn("There was a problem recovering stored Newick tree: \n" + + tree.getNewick()); + continue; + } if (tree.getId() != null) { // perhaps bind the tree id to something ? @@ -4205,13 +4438,6 @@ public class Jalview2XML tp.getTreeCanvas().setAssociatedPanel(ap); // af.alignPanel; } tp.getTreeCanvas().setApplyToAllViews(tree.isLinkToAllViews()); - if (tp == null) - { - warn("There was a problem recovering stored Newick tree: \n" - + tree.getNewick()); - continue; - } - tp.fitToWindow.setState(safeBoolean(tree.isFitToWindow())); tp.fitToWindow_actionPerformed(null); @@ -4294,7 +4520,7 @@ public class Jalview2XML int height = safeInt(structureState.getHeight()); // Probably don't need to do this anymore... - // Desktop.desktop.getComponentAt(x, y); + // Desktop.getDesktop().getComponentAt(x, y); // TODO: NOW: check that this recovers the PDB file correctly. String pdbFile = loadPDBFile(jprovider, pdbid.getId(), pdbid.getFile()); @@ -4450,7 +4676,7 @@ public class Jalview2XML */ String viewerJarEntryName = getViewerJarEntryName(data.getViewId()); chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName, - "chimera", null); + "chimera", ".py"); Set> fileData = data.getFileData() .entrySet(); @@ -4536,7 +4762,8 @@ public class Jalview2XML String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\"); filedat = oldFiles.get(new File(reformatedOldFilename)); } - newFileLoc.append(Platform.escapeString(filedat.getFilePath())); + newFileLoc + .append(Platform.escapeBackslashes(filedat.getFilePath())); pdbfilenames.add(filedat.getFilePath()); pdbids.add(filedat.getPdbId()); seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0])); @@ -4613,9 +4840,11 @@ 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() + + // BH again was invokeAndWait + // try + // { + javax.swing.SwingUtilities.invokeLater(new Runnable() { @Override public void run() @@ -4642,14 +4871,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(); + // } } @@ -4778,7 +5007,7 @@ public class Jalview2XML { try { - frames = Desktop.desktop.getAllFrames(); + frames = Desktop.getDesktopPane().getAllFrames(); } catch (ArrayIndexOutOfBoundsException e) { // occasional No such child exceptions are thrown here... @@ -4848,27 +5077,28 @@ public class Jalview2XML } } - AlignFrame loadViewport(String file, List JSEQ, - List hiddenSeqs, AlignmentI al, - JalviewModel jm, Viewport view, String uniqueSeqSetId, - String viewId, List autoAlan) + AlignFrame loadViewport(String fileName, File file, List JSEQ, + List hiddenSeqs, AlignmentI al, JalviewModel jm, + Viewport view, String uniqueSeqSetId, String viewId, + List autoAlan) { AlignFrame af = null; af = new AlignFrame(al, safeInt(view.getWidth()), - safeInt(view.getHeight()), uniqueSeqSetId, viewId) -// { -// -// @Override -// protected void processKeyEvent(java.awt.event.KeyEvent e) { -// System.out.println("Jalview2XML AF " + e); -// super.processKeyEvent(e); -// -// } -// -// } + safeInt(view.getHeight()), uniqueSeqSetId, viewId) + // { + // + // @Override + // protected void processKeyEvent(java.awt.event.KeyEvent e) { + // System.out.println("Jalview2XML AF " + e); + // super.processKeyEvent(e); + // + // } + // + // } ; - - af.setFileName(file, FileFormat.Jalview); + af.alignPanel.setHoldRepaint(true); + af.setFile(fileName, file, null, FileFormat.Jalview); + af.setFileObject(jarFile); // BH 2019 JAL-3436 final AlignViewport viewport = af.getViewport(); for (int i = 0; i < JSEQ.size(); i++) @@ -4943,9 +5173,8 @@ public class Jalview2XML viewport.setColourText(safeBoolean(view.isShowColourText())); - viewport - .setConservationSelected( - safeBoolean(view.isConservationSelected())); + viewport.setConservationSelected( + safeBoolean(view.isConservationSelected())); viewport.setIncrement(safeInt(view.getConsThreshold())); viewport.setShowJVSuffix(safeBoolean(view.isShowFullId())); viewport.setRightAlignIds(safeBoolean(view.isRightAlignIds())); @@ -4976,8 +5205,18 @@ public class Jalview2XML viewport.setViewName(view.getViewName()); af.setInitialTabVisible(); } - af.setBounds(safeInt(view.getXpos()), safeInt(view.getYpos()), - safeInt(view.getWidth()), safeInt(view.getHeight())); + int x = safeInt(view.getXpos()); + int y = safeInt(view.getYpos()); + int w = safeInt(view.getWidth()); + int h = safeInt(view.getHeight()); + // // BH we cannot let the title bar go off the top + // if (Platform.isJS()) + // { + // x = Math.max(50 - w, x); + // y = Math.max(0, y); + // } + + af.setBounds(x, y, w, h); // startSeq set in af.alignPanel.updateLayout below af.alignPanel.updateLayout(); ColourSchemeI cs = null; @@ -5021,9 +5260,8 @@ public class Jalview2XML af.changeColour(cs); viewport.setColourAppliesToAllGroups(true); - viewport - .setShowSequenceFeatures( - safeBoolean(view.isShowSequenceFeatures())); + viewport.setShowSequenceFeatures( + safeBoolean(view.isShowSequenceFeatures())); viewport.setCentreColumnLabels(view.isCentreColumnLabels()); viewport.setIgnoreGapsConsensus(view.isIgnoreGapsinConsensus(), null); @@ -5036,6 +5274,9 @@ public class Jalview2XML viewport.setShowNPFeats(safeBoolean(view.isShowNPfeatureTooltip())); viewport.setShowGroupConsensus(view.isShowGroupConsensus()); viewport.setShowGroupConservation(view.isShowGroupConservation()); + viewport.setShowComplementFeatures(view.isShowComplementFeatures()); + viewport.setShowComplementFeaturesOnTop( + view.isShowComplementFeaturesOnTop()); // recover feature settings if (jm.getFeatureSettings() != null) @@ -5044,13 +5285,13 @@ public class Jalview2XML .getFeatureRenderer(); FeaturesDisplayed fdi; viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed()); - String[] renderOrder = new String[jm.getFeatureSettings() - .getSetting().size()]; + String[] renderOrder = new String[jm.getFeatureSettings().getSetting() + .size()]; Map featureColours = new Hashtable<>(); Map featureOrder = new Hashtable<>(); - for (int fs = 0; fs < jm.getFeatureSettings() - .getSetting().size(); fs++) + for (int fs = 0; fs < jm.getFeatureSettings().getSetting() + .size(); fs++) { Setting setting = jm.getFeatureSettings().getSetting().get(fs); String featureType = setting.getType(); @@ -5062,8 +5303,8 @@ public class Jalview2XML .getMatcherSet(); if (filters != null) { - FeatureMatcherSetI filter = Jalview2XML - .parseFilter(featureType, filters); + FeatureMatcherSetI filter = Jalview2XML.parseFilter(featureType, + filters); if (!filter.isEmpty()) { fr.setFeatureFilter(featureType, filter); @@ -5095,8 +5336,7 @@ public class Jalview2XML float max = setting.getMax() == null ? 1f : setting.getMax().floatValue(); FeatureColourI gc = new FeatureColour(maxColour, minColour, - maxColour, - noValueColour, min, max); + maxColour, noValueColour, min, max); if (setting.getAttributeName().size() > 0) { gc.setAttributeName(setting.getAttributeName().toArray( @@ -5130,8 +5370,7 @@ public class Jalview2XML } else { - featureColours.put(featureType, - new FeatureColour(maxColour)); + featureColours.put(featureType, new FeatureColour(maxColour)); } renderOrder[fs] = featureType; if (setting.getOrder() != null) @@ -5140,7 +5379,7 @@ public class Jalview2XML } else { - featureOrder.put(featureType, new Float( + featureOrder.put(featureType, Float.valueOf( fs / jm.getFeatureSettings().getSetting().size())); } if (safeBoolean(setting.isDisplay())) @@ -5152,7 +5391,7 @@ public class Jalview2XML for (int gs = 0; gs < jm.getFeatureSettings().getGroup().size(); gs++) { Group grp = jm.getFeatureSettings().getGroup().get(gs); - fgtable.put(grp.getName(), new Boolean(grp.isDisplay())); + fgtable.put(grp.getName(), Boolean.valueOf(grp.isDisplay())); } // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder, // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ? @@ -5199,8 +5438,9 @@ public class Jalview2XML String complementaryViewId = view.getComplementId(); if (complementaryViewId == null) { - Desktop.addInternalFrame(af, view.getTitle(), + Dimension dim = Platform.getDimIfEmbedded(af, safeInt(view.getWidth()), safeInt(view.getHeight())); + Desktop.addInternalFrame(af, view.getTitle(), dim.width, dim.height); // recompute any autoannotation af.alignPanel.updateAnnotation(false, true); reorderAutoannotation(af, al, autoAlan); @@ -5458,16 +5698,16 @@ public class Jalview2XML String id = object.getViewport().get(0).getSequenceSetId(); if (skipList.containsKey(id)) { - if (Cache.log != null && Cache.log.isDebugEnabled()) - { - Cache.log.debug("Skipping seuqence set id " + id); - } + if (Cache.log != null && Cache.log.isDebugEnabled()) + { + Cache.log.debug("Skipping seuqence set id " + id); + } return true; } return false; } - public void addToSkipList(AlignFrame af) + protected void addToSkipList(AlignFrame af) { if (skipList == null) { @@ -5476,7 +5716,7 @@ public class Jalview2XML skipList.put(af.getViewport().getSequenceSetId(), af); } - public void clearSkipList() + protected void clearSkipList() { if (skipList != null) { @@ -5545,8 +5785,8 @@ public class Jalview2XML SequenceI[] dsseqs = new SequenceI[dseqs.size()]; dseqs.copyInto(dsseqs); ds = new jalview.datamodel.Alignment(dsseqs); - debug("Created new dataset " + vamsasSet.getDatasetId() - + " for alignment " + System.identityHashCode(al)); +// debug("Jalview2XML Created new dataset " + vamsasSet.getDatasetId() +// + " for alignment " + System.identityHashCode(al)); addDatasetRef(vamsasSet.getDatasetId(), ds); } // set the dataset for the newly imported alignment. @@ -5825,13 +6065,29 @@ public class Jalview2XML return datasetId; } + /** + * Add any saved DBRefEntry's to the sequence. An entry flagged as 'locus' is + * constructed as a special subclass GeneLocus. + * + * @param datasetSequence + * @param sequence + */ private void addDBRefs(SequenceI datasetSequence, Sequence sequence) { for (int d = 0; d < sequence.getDBRef().size(); d++) { DBRef dr = sequence.getDBRef().get(d); - jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry( - dr.getSource(), dr.getVersion(), dr.getAccessionId()); + DBRefEntry entry; + if (dr.isLocus()) + { + entry = new GeneLocus(dr.getSource(), dr.getVersion(), + dr.getAccessionId()); + } + else + { + entry = new DBRefEntry(dr.getSource(), dr.getVersion(), + dr.getAccessionId()); + } if (dr.getMapping() != null) { entry.setMap(addMapping(dr.getMapping())); @@ -5919,7 +6175,6 @@ public class Jalview2XML jmap.setTo(djs); incompleteSeqs.put(sqid, djs); seqRefIds.put(sqid, djs); - } jalview.bin.Cache.log.debug("about to recurse on addDBRefs."); addDBRefs(djs, ms); @@ -5957,9 +6212,11 @@ public class Jalview2XML viewportsAdded.clear(); - AlignFrame af = loadFromObject(jm, null, false, null); + AlignFrame af = loadFromObject(jm, null, null, false, null); af.getAlignPanels().clear(); af.closeMenuItem_actionPerformed(true); + af.alignPanel.setHoldRepaint(false); + this.jarFile = null; /* * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0; @@ -6103,7 +6360,7 @@ public class Jalview2XML } else { - Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id); + Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id); } } } @@ -6318,8 +6575,10 @@ public class Jalview2XML axis.getXPos(), axis.getYPos(), axis.getZPos()); } + Dimension dim = Platform.getDimIfEmbedded(panel, 475, 450); Desktop.addInternalFrame(panel, MessageManager.formatMessage( - "label.calc_title", "PCA", modelName), 475, 450); + "label.calc_title", "PCA", modelName), dim.width, + dim.height); } } catch (Exception ex) { @@ -6577,7 +6836,7 @@ public class Jalview2XML maxcol = new Color(Integer.parseInt(colourModel.getRGB(), 16)); } catch (Exception e) { - Cache.log.warn("Couldn't parse out graduated feature color.", e); + Cache.log.warn("Couldn't parse out graduated feature color.", e); } NoValueColour noCol = colourModel.getNoValueColour();