X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fext%2Frbvi%2Fchimera%2FJalviewChimeraBinding.java;h=501e34550923c97a273c9f1873f372f1beaa6bd3;hb=ee778ac34b35c8d8fef03f1f3a58efb7d5be650a;hp=415fc1b2a631d6319350f076bf2a1c8f4c7d73fc;hpb=17e77c3f2949a0729322b4a8d907f3f34b6a9914;p=jalview.git diff --git a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java index 415fc1b..501e345 100644 --- a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java +++ b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java @@ -1,6 +1,6 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9) - * Copyright (C) 2015 The Jalview Authors + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * @@ -23,6 +23,7 @@ package jalview.ext.rbvi.chimera; import jalview.api.AlignmentViewPanel; import jalview.api.FeatureRenderer; import jalview.api.SequenceRenderer; +import jalview.api.structures.JalviewStructureDisplayI; import jalview.bin.Cache; import jalview.datamodel.AlignmentI; import jalview.datamodel.ColumnSelection; @@ -101,16 +102,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel private String lastCommand; - private boolean loadedInline; - - /** - * current set of model filenames loaded - */ - String[] modelFileNames = null; - - String lastMousedOverAtomSpec; - - private List lastReply; + String lastHighlightCommand; /* * incremented every time a load notification is successfully handled - @@ -119,6 +111,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel */ private long loadNotifiesHandled = 0; + private Thread chimeraMonitor; + /** * Open a PDB structure file in Chimera and set up mappings from Jalview. * @@ -204,8 +198,38 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel String protocol) { super(ssm, pdbentry, sequenceIs, chains, protocol); - viewer = new ChimeraManager( - new ext.edu.ucsf.rbvi.strucviz2.StructureManager(true)); + viewer = new ChimeraManager(new StructureManager(true)); + } + + /** + * Starts a thread that waits for the Chimera process to finish, so that we + * can then close the associated resources. This avoids leaving orphaned + * Chimera viewer panels in Jalview if the user closes Chimera. + */ + protected void startChimeraProcessMonitor() + { + final Process p = viewer.getChimeraProcess(); + chimeraMonitor = new Thread(new Runnable() + { + + @Override + public void run() + { + try + { + p.waitFor(); + JalviewStructureDisplayI display = getViewer(); + if (display != null) + { + display.closeViewer(false); + } + } catch (InterruptedException e) + { + // exit thread if Chimera Viewer is closed in Jalview + } + } + }); + chimeraMonitor.start(); } /** @@ -290,6 +314,10 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel lastCommand = null; viewer = null; + if (chimeraMonitor != null) + { + chimeraMonitor.interrupt(); + } releaseUIResources(); } @@ -570,23 +598,29 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel /** * Launch Chimera, unless an instance linked to this object is already - * running. Returns true if chimera is successfully launched, or already + * running. Returns true if Chimera is successfully launched, or already * running, else false. * * @return */ public boolean launchChimera() { - if (!viewer.isChimeraLaunched()) - { - return viewer.launchChimera(StructureManager.getChimeraPaths()); - } if (viewer.isChimeraLaunched()) { return true; } - log("Failed to launch Chimera!"); - return false; + + boolean launched = viewer.launchChimera(StructureManager + .getChimeraPaths()); + if (launched) + { + startChimeraProcessMonitor(); + } + else + { + log("Failed to launch Chimera!"); + } + return launched; } /** @@ -617,7 +651,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel if (lastCommand == null || !lastCommand.equals(command)) { // trim command or it may never find a match in the replyLog!! - lastReply = viewer.sendChimeraCommand(command.trim(), logResponse); + List lastReply = viewer.sendChimeraCommand(command.trim(), + logResponse); if (logResponse && debug) { log("Response from command ('" + command + "') was:\n" + lastReply); @@ -715,17 +750,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel // End StructureListener // ////////////////////////// - public Color getColour(int atomIndex, int pdbResNum, String chain, - String pdbfile) - { - if (getModelNum(pdbfile) < 0) - { - return null; - } - log("get model / residue colour attribute unimplemented"); - return null; - } - /** * returns the current featureRenderer that should be used to colour the * structures @@ -795,15 +819,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel } /** - * map from string to applet - */ - public Map getRegistryInfo() - { - // TODO Auto-generated method stub - return null; - } - - /** * returns the current sequenceRenderer that should be used to colour the * structures * @@ -815,22 +830,22 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel AlignmentViewPanel alignment); /** - * Construct and send a command to highlight zero, one or more atoms. - * - *
-   * Done by generating a command like (to 'highlight' position 44)
-   *   show #0:44.C
-   * 
+ * Construct and send a command to highlight zero, one or more atoms. We do + * this by sending an "rlabel" command to show the residue label at that + * position. */ @Override public void highlightAtoms(List atoms) { - if (atoms == null) + if (atoms == null || atoms.size() == 0) { return; } - StringBuilder atomSpecs = new StringBuilder(); + + StringBuilder cmd = new StringBuilder(128); boolean first = true; + boolean found = false; + for (AtomSpec atom : atoms) { int pdbResNum = atom.getPdbResNum(); @@ -839,39 +854,46 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel List cms = chimeraMaps.get(pdbfile); if (cms != null && !cms.isEmpty()) { - /* - * Formatting as #0:34.A,#1:33.A doesn't work as desired, so instead we - * concatenate multiple 'show' commands - */ - atomSpecs.append(first ? "" : ";show "); + if (first) + { + cmd.append("rlabel #").append(cms.get(0).getModelNumber()) + .append(":"); + } + else + { + cmd.append(","); + } first = false; - atomSpecs.append("#" + cms.get(0).getModelNumber()); - atomSpecs.append(":" + pdbResNum); + cmd.append(pdbResNum); if (!chain.equals(" ")) { - atomSpecs.append("." + chain); + cmd.append(".").append(chain); } + found = true; } } - String atomSpec = atomSpecs.toString(); + String command = cmd.toString(); /* - * Avoid repeated commands for the same residue + * avoid repeated commands for the same residue */ - if (atomSpec.equals(lastMousedOverAtomSpec)) + if (command.equals(lastHighlightCommand)) { return; } - StringBuilder command = new StringBuilder(32); - viewerCommandHistory(false); - if (atomSpec.length() > 0) + /* + * unshow the label for the previous residue + */ + if (lastHighlightCommand != null) { - command.append("show ").append(atomSpec); - viewer.sendChimeraCommand(command.toString(), false); + viewer.sendChimeraCommand("~" + lastHighlightCommand, false); } - viewerCommandHistory(true); - this.lastMousedOverAtomSpec = atomSpec; + if (found) + { + viewer.sendChimeraCommand(command, false); + } + this.lastHighlightCommand = command; } /** @@ -994,6 +1016,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel */ public abstract void refreshGUI(); + @Override public void setLoadingFromArchive(boolean loadingFromArchive) { this.loadingFromArchive = loadingFromArchive; @@ -1004,6 +1027,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel * @return true if Chimeral is still restoring state or loading is still going * on (see setFinsihedLoadingFromArchive) */ + @Override public boolean isLoadingFromArchive() { return loadingFromArchive && !loadingFinished; @@ -1015,6 +1039,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel * * @param finishedLoading */ + @Override public void setFinishedLoadingFromArchive(boolean finishedLoading) { loadingFinished = finishedLoading; @@ -1115,4 +1140,32 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel { sendChimeraCommand("focus", false); } + + /** + * Send a 'show' command for all atoms in the currently selected columns + * + * TODO: pull up to abstract structure viewer interface + * + * @param vp + */ + public void highlightSelection(AlignmentViewPanel vp) + { + List cols = vp.getAlignViewport().getColumnSelection() + .getSelected(); + AlignmentI alignment = vp.getAlignment(); + StructureSelectionManager sm = getSsm(); + for (SequenceI seq : alignment.getSequences()) + { + /* + * convert selected columns into sequence positions + */ + int[] positions = new int[cols.size()]; + int i = 0; + for (Integer col : cols) + { + positions[i++] = seq.findPosition(col); + } + sm.highlightStructure(this, seq, positions); + } + } }