X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fappletgui%2FAppletJmol.java;h=980985914e65256fe435aada4bd5d9d3f63c2242;hb=f8456d4c0b253ae32a4b569e12bb8bf7f7096d65;hp=ff0f5aeeecd81219cb511ae6ef6bbae153f8d4b7;hpb=c68ebaddf1925d9458aab5f2fea6e6f3240b3b99;p=jalview.git diff --git a/src/jalview/appletgui/AppletJmol.java b/src/jalview/appletgui/AppletJmol.java index ff0f5ae..9809859 100644 --- a/src/jalview/appletgui/AppletJmol.java +++ b/src/jalview/appletgui/AppletJmol.java @@ -21,6 +21,7 @@ import java.util.*; import java.awt.*; import java.awt.event.*; +import jalview.api.SequenceStructureBinding; import jalview.datamodel.*; import jalview.structure.*; import jalview.io.*; @@ -34,7 +35,7 @@ import org.jmol.viewer.JmolConstants; import jalview.schemes.*; public class AppletJmol extends EmbmenuFrame implements StructureListener, - JmolStatusListener, KeyListener, ActionListener, ItemListener + JmolStatusListener, KeyListener, ActionListener, ItemListener, SequenceStructureBinding { Menu fileMenu = new Menu("File"); @@ -189,8 +190,9 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, embedMenuIfNeeded(renderPanel); this.add(renderPanel, BorderLayout.CENTER); viewer = JmolViewer.allocateViewer(renderPanel, - new SmarterJmolAdapter(), "jalviewJmol", ap.av.applet.getDocumentBase(), - ap.av.applet.getCodeBase(), "", this); + new SmarterJmolAdapter(), "jalviewJmol", ap.av.applet + .getDocumentBase(), ap.av.applet.getCodeBase(), "", + this); jmolpopup = JmolPopup.newJmolPopup(viewer, true, "Jmol", true); @@ -270,6 +272,21 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, jalview.bin.JalviewLite.addFrame(this, "Jmol", 400, 400); } + /** + * create a new binding between structures in an existing jmol viewer instance and + * an alignpanel with sequences that have existing PDBFile entries. Note, this does not open a new Jmol window, + * or modify the display of the structures in the original jmol window. + * @param viewer2 + * @param alignPanel + * @param seqs - sequences to search for associations + */ + public AppletJmol(JmolViewer viewer2, AlignmentPanel alignPanel, + SequenceI[] seqs) + { + + // TODO Auto-generated constructor stub + } + public void loadInline(String string) { loadedInline = true; @@ -299,14 +316,30 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, void centerViewer() { + jmolHistory(false); StringBuffer cmd = new StringBuffer(); + String lbl; + int mlength, p,mnum; for (int i = 0; i < chainMenu.getItemCount(); i++) { if (chainMenu.getItem(i) instanceof CheckboxMenuItem) { CheckboxMenuItem item = (CheckboxMenuItem) chainMenu.getItem(i); if (item.getState()) - cmd.append(":" + item.getLabel() + " or "); + { + lbl = item.getLabel(); + mlength = 0; + do + { + p = mlength; + mlength = lbl.indexOf(":", p); + } while (p < mlength && mlength < (lbl.length() - 2)); + mnum = 1+getModelNum(lbl.substring(0, mlength)); + if (mnum>0) + {cmd.append(":" + lbl.substring(mlength + 1) + " /" + + mnum + " or "); + } + } } } @@ -316,25 +349,42 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, viewer .evalString("select *;restrict " + cmd + ";cartoon;center " + cmd); + jmolHistory(true); + } + + private int getModelNum(String modelFileName) + { + String[] mfn = getPdbFile(); + if (mfn == null) + { + return -1; + } + for (int i = 0; i < mfn.length; i++) + { + if (mfn[i].equalsIgnoreCase(modelFileName)) + return i; + } + return -1; } void closeViewer() { viewer.setModeMouse(org.jmol.viewer.JmolConstants.MOUSE_NONE); + // remove listeners for all structures in viewer + StructureSelectionManager.getStructureSelectionManager() + .removeStructureViewerListener(this, this.getPdbFile()); + // and shut down jmol viewer.evalStringQuiet("zap"); viewer.setJmolStatusListener(null); - viewer = null; - // We'll need to find out what other - // listeners need to be shut down in Jmol - StructureSelectionManager.getStructureSelectionManager() - .removeStructureViewerListener(this, pdbentry.getId()); + viewer = null; this.setVisible(false); } public void actionPerformed(ActionEvent evt) { + jmolHistory(false); if (evt.getSource() == mappingMenuItem) { jalview.appletgui.CutAndPasteTransfer cap = new jalview.appletgui.CutAndPasteTransfer( @@ -417,8 +467,12 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, centerViewer(); allChainsSelected = false; } + jmolHistory(true); + } + private void jmolHistory(boolean enable) + { + viewer.setBooleanProperty("history", enable); } - public void setJalviewColourScheme(ColourSchemeI cs) { colourBySequence = false; @@ -430,6 +484,7 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, String res; int index; Color col; + jmolHistory(false); Enumeration en = ResidueProperties.aa3Hash.keys(); StringBuffer command = new StringBuffer("select *;color white;"); @@ -447,6 +502,7 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, } viewer.evalStringQuiet(command.toString()); + jmolHistory(true); } public void itemStateChanged(ItemEvent evt) @@ -480,24 +536,42 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, { } + String[] modelFileNames = null; + // //////////////////////////////// // /StructureListener - public String getPdbFile() + public String[] getPdbFile() { - return "???"; + if (modelFileNames == null) + { + String mset[] = new String[viewer.getModelCount()]; + for (int i = 0; i < mset.length; i++) + { + mset[i] = viewer.getModelFileName(i); + } + modelFileNames = mset; + } + return modelFileNames; } String lastMessage; + // jmol/ssm only public void mouseOverStructure(int atomIndex, String strInfo) { int pdbResNum; - - int chainSeparator = strInfo.indexOf(":"); + int mdlSep = strInfo.indexOf("/"); + int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1; if (chainSeparator == -1) + { chainSeparator = strInfo.indexOf("."); - + if (mdlSep > -1 && mdlSep < chainSeparator) + { + chainSeparator1 = chainSeparator; + chainSeparator = mdlSep; + } + } pdbResNum = Integer.parseInt(strInfo.substring( strInfo.indexOf("]") + 1, chainSeparator)); @@ -511,8 +585,27 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, chainId = " "; } + String pdbfilename = pdbentry.getFile(); + if (mdlSep > -1) + { + if (chainSeparator1 == -1) + { + chainSeparator1 = strInfo.indexOf(".", mdlSep); + } + String mdlId = (chainSeparator1 > -1) ? strInfo.substring(mdlSep + 1, + chainSeparator1) : strInfo.substring(mdlSep + 1); + try + { + // recover PDB filename for the model hovered over. + pdbfilename = viewer + .getModelFileName(new Integer(mdlId).intValue() - 1); + } catch (Exception e) + { + } + ; + } if (lastMessage == null || !lastMessage.equals(strInfo)) - ssm.mouseOverStructure(pdbResNum, chainId, pdbentry.getFile()); + ssm.mouseOverStructure(pdbResNum, chainId, pdbfilename); lastMessage = strInfo; } @@ -521,31 +614,42 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, StringBuffer eval = new StringBuffer(); + // jmol/ssm only public void highlightAtom(int atomIndex, int pdbResNum, String chain, String pdbfile) { - if (!pdbfile.equals(pdbentry.getFile())) + int mdlNum = 1+getModelNum(pdbfile); + if (mdlNum==0) + { return; + } + jmolHistory(false); + // if (!pdbfile.equals(pdbentry.getFile())) + // return; if (resetLastRes.length() > 0) { viewer.evalStringQuiet(resetLastRes.toString()); } eval.setLength(0); - eval.append("select " + pdbResNum); + eval.append("select " + pdbResNum); // +modelNum resetLastRes.setLength(0); - resetLastRes.append("select " + pdbResNum); + resetLastRes.append("select " + pdbResNum); // +modelNum - eval.append(":"); - resetLastRes.append(":"); if (!chain.equals(" ")) { + eval.append(":"); + resetLastRes.append(":"); eval.append(chain); resetLastRes.append(chain); } - + // if (mdlNum != 0) + { + eval.append(" /" + (mdlNum)); + resetLastRes.append("/" + (mdlNum)); + } eval.append(";wireframe 100;" + eval.toString() + " and not hetero;"); resetLastRes.append(";wireframe 0;" + resetLastRes.toString() @@ -554,6 +658,7 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, eval.append("spacefill 200;select none"); viewer.evalStringQuiet(eval.toString()); + jmolHistory(true); } @@ -584,12 +689,7 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, if (!colourBySequence) return; - - StructureMapping[] mapping = ssm.getMapping(pdbentry.getFile()); - - if (mapping.length < 1) - return; - + String[] files = getPdbFile(); SequenceRenderer sr = new SequenceRenderer(ap.av); boolean showFeatures = false; @@ -607,62 +707,74 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, StringBuffer command = new StringBuffer(); - int lastPos = -1; - for (int s = 0; s < sequence.length; s++) + for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++) { - for (int sp, m = 0; m < mapping.length; m++) + StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]); + + if (mapping == null || mapping.length < 1) + continue; + + int lastPos = -1; + for (int s = 0; s < sequence.length; s++) { - if (mapping[m].getSequence() == sequence[s] - && (sp = ap.av.alignment.findIndex(sequence[s])) > -1) + for (int sp, m = 0; m < mapping.length; m++) { - SequenceI asp = ap.av.alignment.getSequenceAt(sp); - for (int r = 0; r < asp.getLength(); r++) + if (mapping[m].getSequence() == sequence[s] + && (sp = ap.av.alignment.findIndex(sequence[s])) > -1) { - // no mapping to gaps in sequence - if (jalview.util.Comparison.isGap(asp.getCharAt(r))) + SequenceI asp = ap.av.alignment.getSequenceAt(sp); + for (int r = 0; r < asp.getLength(); r++) { - continue; + // no mapping to gaps in sequence + if (jalview.util.Comparison.isGap(asp.getCharAt(r))) + { + continue; + } + int pos = mapping[m].getPDBResNum(asp.findPosition(r)); + + if (pos < 1 || pos == lastPos) + continue; + + lastPos = pos; + + Color col = sr.getResidueBoxColour(sequence[s], r); + + if (showFeatures) + col = fr.findFeatureColour(col, sequence[s], r); + String newSelcom = (mapping[m].getChain() != " " ? ":" + + mapping[m].getChain() : "") + + "/" + + (pdbfnum + 1) + + ".1" + + ";color[" + + col.getRed() + + "," + + col.getGreen() + + "," + + col.getBlue() + "]"; + if (command.toString().endsWith(newSelcom)) + { + command = condenseCommand(command.toString(), pos); + continue; + } + // TODO: deal with case when buffer is too large for Jmol to parse + // - execute command and flush + + command.append(";select " + pos); + command.append(newSelcom); } - int pos = mapping[m].getPDBResNum(asp.findPosition(r)); - - if (pos < 1 || pos == lastPos) - continue; - - lastPos = pos; - - Color col = sr.getResidueBoxColour(sequence[s], r); - - if (showFeatures) - col = fr.findFeatureColour(col, sequence[s], r); - - if (command.toString().endsWith( - ":" + mapping[m].getChain() + ";color[" + col.getRed() - + "," + col.getGreen() + "," + col.getBlue() - + "]")) - { - command = condenseCommand(command.toString(), pos); - continue; - } - - command.append(";select " + pos); - - if (!mapping[m].getChain().equals(" ")) - { - command.append(":" + mapping[m].getChain()); - } - - command.append(";color[" + col.getRed() + "," + col.getGreen() - + "," + col.getBlue() + "]"); + break; } - break; } } } + jmolHistory(false); if (lastCommand == null || !lastCommand.equals(command.toString())) { viewer.evalStringQuiet(command.toString()); } + jmolHistory(true); lastCommand = command.toString(); } @@ -704,7 +816,7 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, { } - public void notifyFileLoaded(String fullPathName, String fileName, + public void notifyFileLoaded(String fullPathName, String fileName2, String modelName, String errorMsg, int modelParts) { if (errorMsg != null) @@ -713,71 +825,93 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, repaint(); return; } - fileLoadingError = null; - - if (fileName != null) + modelFileNames = null; + + String[] modelfilenames = getPdbFile(); + ssm = StructureSelectionManager.getStructureSelectionManager(); + boolean modelsloaded=false; + for (int modelnum = 0; modelnum < modelfilenames.length; modelnum++) { - // TODO: do some checking using the modelPts number of parts against our own estimate of the number of chains - // FILE LOADED OK - jmolpopup.updateComputedMenus(); - viewer - .evalStringQuiet("select backbone;restrict;cartoon;wireframe off;spacefill off"); - - ssm = StructureSelectionManager.getStructureSelectionManager(); - MCview.PDBfile pdb; - if (loadedInline) + String fileName = modelfilenames[modelnum]; + if (fileName != null) { - pdb = ssm.setMapping(sequence, chains, pdbentry.getFile(), - AppletFormatAdapter.PASTE); - pdbentry.setFile("INLINE" + pdb.id); - } - else - { - // TODO: Jmol can in principle retrieve from CLASSLOADER but this needs - // to be tested. See mantis bug - // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605 + // search pdbentries and sequences to find correct pdbentry and sequence[] pair for this filename + if (pdbentry.getFile().equals(fileName)) + { + modelsloaded=true; + MCview.PDBfile pdb; + if (loadedInline) + { + pdb = ssm.setMapping(sequence, chains, pdbentry.getFile(), + AppletFormatAdapter.PASTE); + pdbentry.setFile("INLINE" + pdb.id); + } + else + { + // TODO: Jmol can in principle retrieve from CLASSLOADER but this + // needs + // to be tested. See mantis bug + // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605 - pdb = ssm.setMapping(sequence, chains, pdbentry.getFile(), - AppletFormatAdapter.URL); + pdb = ssm.setMapping(sequence, chains, pdbentry.getFile(), + AppletFormatAdapter.URL); - } + } - pdbentry.setId(pdb.id); + pdbentry.setId(pdb.id); - ssm.addStructureViewerListener(this); + Vector chains = new Vector(); + for (int i = 0; i < pdb.chains.size(); i++) + { + chains.addElement(new String(pdb.id + ":" + + ((MCview.PDBChain) pdb.chains.elementAt(i)).id)); + } + setChainMenuItems(chains); - Vector chains = new Vector(); - for (int i = 0; i < pdb.chains.size(); i++) - { - chains.addElement(((MCview.PDBChain) pdb.chains.elementAt(i)).id); - } - setChainMenuItems(chains); + colourBySequence(ap); - colourBySequence(ap); + StringBuffer title = new StringBuffer(sequence[0].getName() + ":" + + pdbentry.getId()); - StringBuffer title = new StringBuffer(sequence[0].getName() + ":" - + pdbentry.getId()); + if (pdbentry.getProperty() != null) + { + if (pdbentry.getProperty().get("method") != null) + { + title.append(" Method: "); + title.append(pdbentry.getProperty().get("method")); + } + if (pdbentry.getProperty().get("chains") != null) + { + title.append(" Chain:"); + title.append(pdbentry.getProperty().get("chains")); + } + } + + this.setTitle(title.toString()); - if (pdbentry.getProperty() != null) - { - if (pdbentry.getProperty().get("method") != null) - { - title.append(" Method: "); - title.append(pdbentry.getProperty().get("method")); } - if (pdbentry.getProperty().get("chains") != null) + else { - title.append(" Chain:"); - title.append(pdbentry.getProperty().get("chains")); + // this is a foreign pdb file that jalview doesn't know about - add it to the dataset + // and try to find a home - either on a matching sequence or as a new sequence. + String pdbcontent = viewer.getData("/" + (modelnum + 1) + ".1", + "PDB"); + // parse pdb file into a chain, etc. + // locate best match for pdb in associated views and add mapping to + // ssm + modelsloaded=true; } } + } + if (modelsloaded) { + // FILE LOADED OK + jmolpopup.updateComputedMenus(); + viewer + .evalStringQuiet("model 0; select backbone;restrict;cartoon;wireframe off;spacefill off"); - this.setTitle(title.toString()); - + ssm.addStructureViewerListener(this); } - else - return; } public void sendConsoleEcho(String strEcho) @@ -813,27 +947,32 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, public void notifyAtomPicked(int atomIndex, String strInfo, String strData) { - if (strData!=null) + if (strData != null) { - System.err.println("Ignoring additional pick data string "+strData); + System.err.println("Ignoring additional pick data string " + strData); } int chainSeparator = strInfo.indexOf(":"); - + int p=0; if (chainSeparator == -1) chainSeparator = strInfo.indexOf("."); String picked = strInfo.substring(strInfo.indexOf("]") + 1, chainSeparator); - - if (strInfo.indexOf(":") > -1) - picked += strInfo.substring(strInfo.indexOf(":") + 1, strInfo + String mdlString=""; + if ((p=strInfo.indexOf(":")) > -1) + picked += strInfo.substring(p + 1, strInfo .indexOf(".")); - picked = "(("+picked+".CA" + ")|("+picked+".P"+"))"; + if ((p=strInfo.indexOf("/"))> -1) + { + mdlString += strInfo.substring(p, strInfo.indexOf(" #")); + } + picked = "((" + picked + ".CA" + mdlString+")|(" + picked + ".P" + mdlString+"))"; + jmolHistory(false); if (!atomsPicked.contains(picked)) { - viewer.evalString("select " + picked + ";label %n %r:%c"); + viewer.evalStringQuiet("select " + picked + ";label %n %r:%c"); atomsPicked.addElement(picked); } else @@ -841,18 +980,19 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, viewer.evalString("select " + picked + ";label off"); atomsPicked.removeElement(picked); } + jmolHistory(true); + } public void notifyAtomHovered(int atomIndex, String strInfo, String data) { - if (data!=null) + if (data != null) { - System.err.println("Ignoring additional hover info: "+data); + System.err.println("Ignoring additional hover info: " + data); } mouseOverStructure(atomIndex, strInfo); } - public void showUrl(String url) { try @@ -885,7 +1025,7 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, public float[][] functionXY(String functionName, int x, int y) { - return null ; + return null; } // /End JmolStatusListener @@ -943,37 +1083,42 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, public void notifyCallback(int type, Object[] data) { - try { - switch (type) + try { - case JmolConstants.CALLBACK_LOADSTRUCT: - notifyFileLoaded((String) data[1], (String) data[2], - (String) data[3], (String) data[4], ((Integer) data[5]).intValue()); - - break; - case JmolConstants.CALLBACK_PICK: - notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1], (String) data[0]); - // also highlight in alignment - case JmolConstants.CALLBACK_HOVER: - notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1], (String) data[0]); - break; - case JmolConstants.CALLBACK_SCRIPT: - notifyScriptTermination((String)data[2], ((Integer)data[3]).intValue()); - break; - case JmolConstants.CALLBACK_ECHO: - sendConsoleEcho((String)data[1]); - break; - case JmolConstants.CALLBACK_MESSAGE: - sendConsoleMessage((data==null) ? ((String) null) : (String)data[1]); - break; - case JmolConstants.CALLBACK_MEASURE: - case JmolConstants.CALLBACK_CLICK: + switch (type) + { + case JmolConstants.CALLBACK_LOADSTRUCT: + notifyFileLoaded((String) data[1], (String) data[2], + (String) data[3], (String) data[4], ((Integer) data[5]) + .intValue()); + + break; + case JmolConstants.CALLBACK_PICK: + notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1], + (String) data[0]); + // also highlight in alignment + case JmolConstants.CALLBACK_HOVER: + notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1], + (String) data[0]); + break; + case JmolConstants.CALLBACK_SCRIPT: + notifyScriptTermination((String) data[2], ((Integer) data[3]) + .intValue()); + break; + case JmolConstants.CALLBACK_ECHO: + sendConsoleEcho((String) data[1]); + break; + case JmolConstants.CALLBACK_MESSAGE: + sendConsoleMessage((data == null) ? ((String) null) + : (String) data[1]); + break; + case JmolConstants.CALLBACK_MEASURE: + case JmolConstants.CALLBACK_CLICK: default: - System.err.println("Unhandled callback "+type+" "+data); + System.err.println("Unhandled callback " + type + " " + data); break; - } - } - catch (Exception e) + } + } catch (Exception e) { System.err.println("Squashed Jmol callback handler error:"); e.printStackTrace(); @@ -994,7 +1139,7 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, case JmolConstants.CALLBACK_ERROR: return true; case JmolConstants.CALLBACK_CLICK: - case JmolConstants.CALLBACK_ANIMFRAME: + case JmolConstants.CALLBACK_ANIMFRAME: case JmolConstants.CALLBACK_MINIMIZATION: case JmolConstants.CALLBACK_RESIZE: case JmolConstants.CALLBACK_SYNC: @@ -1005,8 +1150,9 @@ public class AppletJmol extends EmbmenuFrame implements StructureListener, public void setCallbackFunction(String callbackType, String callbackFunction) { - System.err.println("Ignoring set-callback request to associate "+callbackType+" with function "+callbackFunction); - + System.err.println("Ignoring set-callback request to associate " + + callbackType + " with function " + callbackFunction); + } }