X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FAppJmol.java;h=dcca874286f0cd78afc91108171a829c4d368fa0;hb=f8456d4c0b253ae32a4b569e12bb8bf7f7096d65;hp=7945fa7d7fe5e954b60f3823b394000e023d3020;hpb=c68ebaddf1925d9458aab5f2fea6e6f3240b3b99;p=jalview.git diff --git a/src/jalview/gui/AppJmol.java b/src/jalview/gui/AppJmol.java index 7945fa7..dcca874 100644 --- a/src/jalview/gui/AppJmol.java +++ b/src/jalview/gui/AppJmol.java @@ -26,6 +26,7 @@ import java.awt.event.*; import java.io.*; import jalview.jbgui.GStructureViewer; +import jalview.api.SequenceStructureBinding; import jalview.bin.Cache; import jalview.datamodel.*; import jalview.gui.*; @@ -41,7 +42,7 @@ import org.jmol.popup.*; import org.jmol.viewer.JmolConstants; public class AppJmol extends GStructureViewer implements StructureListener, - JmolStatusListener, Runnable + JmolStatusListener, Runnable, SequenceStructureBinding { JmolViewer viewer; @@ -280,14 +281,32 @@ public class AppJmol extends GStructureViewer 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 JCheckBoxMenuItem) { JCheckBoxMenuItem item = (JCheckBoxMenuItem) chainMenu.getItem(i); if (item.isSelected()) - cmd.append(":" + item.getText() + " or "); + { lbl = item.getText(); + mlength = 0; + do + { + p = mlength; + mlength = lbl.indexOf(":", p); + } while (p < mlength && mlength < (lbl.length() - 2)); + if (pdbentry.getId().equals(lbl.substring(0,mlength))) + { + mnum = 1+getModelNum(pdbentry.getFile()); + if (mnum>0) + {cmd.append(":" + lbl.substring(mlength + 1) + " /" + + mnum + " or "); + } + } + } } } @@ -296,19 +315,33 @@ public class AppJmol extends GStructureViewer implements StructureListener, viewer.evalStringQuiet("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, 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.getFile()); } public void run() @@ -451,15 +484,19 @@ public class AppJmol extends GStructureViewer implements StructureListener, { colourBySequence = false; seqColour.setSelected(false); + jmolHistory(false); viewer.evalStringQuiet("select *;color chain"); + jmolHistory(true); } public void chargeColour_actionPerformed(ActionEvent actionEvent) { colourBySequence = false; seqColour.setSelected(false); + jmolHistory(false); viewer.evalStringQuiet("select *;color white;select ASP,GLU;color red;" + "select LYS,ARG;color blue;select CYS;color yellow"); + jmolHistory(true); } public void zappoColour_actionPerformed(ActionEvent actionEvent) @@ -499,6 +536,7 @@ public class AppJmol extends GStructureViewer implements StructureListener, public void setJalviewColourScheme(ColourSchemeI cs) { + jmolHistory(false); colourBySequence = false; seqColour.setSelected(false); @@ -525,6 +563,7 @@ public class AppJmol extends GStructureViewer implements StructureListener, } viewer.evalStringQuiet(command.toString()); + jmolHistory(true); } public void userColour_actionPerformed(ActionEvent actionEvent) @@ -539,10 +578,16 @@ public class AppJmol extends GStructureViewer implements StructureListener, if (col != null) { + jmolHistory(false); viewer.evalStringQuiet("background [" + col.getRed() + "," + col.getGreen() + "," + col.getBlue() + "];"); + jmolHistory(true); } } + private void jmolHistory(boolean enable) + { + viewer.setBooleanProperty("history", enable); + } public void jmolHelp_actionPerformed(ActionEvent actionEvent) { @@ -554,39 +599,122 @@ public class AppJmol extends GStructureViewer implements StructureListener, { } } + String[] modelFileNames = null; // //////////////////////////////// // /StructureListener - public String getPdbFile() + public String[] getPdbFile() { - return pdbentry.getFile(); + if (modelFileNames == null) + { + String mset[] = new String[viewer.getModelCount()]; + for (int i = 0; i < mset.length; i++) + { + try { + String mname = viewer.getModelFileName(i); + if (mname==null) + { + System.err.println("Model "+i+" has no filename!"); + continue; + } + File fpath = new File(mname); + mset[i] = fpath.toString(); + } catch (Exception e) + { + System.err.println("Couldn't parse "+viewer.getModelFileName(i)+" as a file!"); + } + } + modelFileNames = mset; + } + return modelFileNames; } Pattern pattern = Pattern - .compile("\\[(.*)\\]([0-9]+)(:[a-zA-Z]*)?\\.([a-zA-Z]+)(/[0-9]*)?"); + .compile("\\[(.*)\\]([0-9]+)(:[a-zA-Z]*)?\\.([a-zA-Z]+).*(/[0-9]*)?"); String lastMessage; public void mouseOverStructure(int atomIndex, String strInfo) { + // copied from AppJmol - will be refactored to binding eventually + int pdbResNum; + 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)); + + String chainId; + + if (strInfo.indexOf(":") > -1) + chainId = strInfo.substring(strInfo.indexOf(":") + 1, strInfo + .indexOf(".")); + else + { + 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, pdbfilename); + + lastMessage = strInfo; +/* + * Old Implementation based on Pattern regex. Matcher matcher = pattern.matcher(strInfo); matcher.find(); matcher.group(1); int pdbResNum = Integer.parseInt(matcher.group(2)); String chainId = matcher.group(3); - + if (chainId != null) chainId = chainId.substring(1, chainId.length()); else { chainId = " "; } + String mdlId = matcher.group(4); + String pdbfilename = pdbentry.getFile(); + if (mdlId!=null && mdlId.length()>0) + { + 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; + lastMessage = strInfo; */ } StringBuffer resetLastRes = new StringBuffer(); @@ -596,38 +724,47 @@ public class AppJmol extends GStructureViewer implements StructureListener, public void highlightAtom(int atomIndex, int pdbResNum, String chain, String pdbfile) { - // TODO: rna: remove CA dependency in select string - 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); } - - eval.append(";wireframe 100;" + eval.toString() + " and not hetero;"); // ".*;"); + // if (mdlNum != 0) + { + eval.append(" /" + (mdlNum)); + resetLastRes.append(" /" + (mdlNum)); + } + eval.append(";wireframe 100;" + eval.toString() + " and not hetero;"); resetLastRes.append(";wireframe 0;" + resetLastRes.toString() - // + ".*;spacefill 0;"); - + " and not hetero;spacefill 0;"); + + " and not hetero; spacefill 0;"); eval.append("spacefill 200;select none"); - // System.out.println("jmol:\n"+eval+"\n"); + viewer.evalStringQuiet(eval.toString()); + jmolHistory(true); } public Color getColour(int atomIndex, int pdbResNum, String chain, @@ -658,11 +795,8 @@ public class AppJmol extends GStructureViewer implements StructureListener, if (!colourBySequence || ap.alignFrame.getCurrentView() != ap.av) return; - StructureMapping[] mapping = ssm.getMapping(pdbentry.getFile()); - - if (mapping.length < 1) - return; - + String[] files = getPdbFile(); + SequenceRenderer sr = new SequenceRenderer(ap.av); boolean showFeatures = false; @@ -679,6 +813,13 @@ public class AppJmol extends GStructureViewer implements StructureListener, } StringBuffer command = new StringBuffer(); + for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++) + { + StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]); + + if (mapping == null || mapping.length < 1) + continue; + int lastPos = -1; for (int sp, s = 0; s < sequence.length; s++) @@ -707,36 +848,38 @@ public class AppJmol extends GStructureViewer implements StructureListener, if (showFeatures) col = fr.findFeatureColour(col, asp, r); - - if (command.toString().endsWith( - ":" + mapping[m].getChain() + ";color[" + col.getRed() - + "," + col.getGreen() + "," + col.getBlue() - + "]")) + 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, 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() + "]"); - + command.append(newSelcom); } break; } } + } } + jmolHistory(false); if (lastCommand == null || !lastCommand.equals(command.toString())) { viewer.evalStringQuiet(command.toString()); } + jmolHistory(true); lastCommand = command.toString(); } @@ -778,7 +921,7 @@ public class AppJmol extends GStructureViewer implements StructureListener, System.out.println("JMOL CREATE IMAGE"); } - public void notifyFileLoaded(String fullPathName, String fileName, + public void notifyFileLoaded(String fullPathName, String fileName2, String modelName, String errorMsg, int modelParts) { if (errorMsg != null) @@ -789,29 +932,38 @@ public class AppJmol extends GStructureViewer implements StructureListener, } fileLoadingError = null; + modelFileNames = null; + + String[] modelfilenames = getPdbFile(); + ssm = StructureSelectionManager.getStructureSelectionManager(); + boolean modelsloaded=false; + for (int modelnum = 0; modelnum < modelfilenames.length; modelnum++) + { + String fileName = modelfilenames[modelnum]; if (fileName != null) { - // TODO: do some checking using the modelPts number of parts against our own estimate of the number of chains + modelsloaded=true; + // search pdbentries and sequences to find correct pdbentry and sequence[] pair for this filename + if (pdbentry.getFile().equals(fileName)) + { + // TODO: do some checking using the modelPts number of parts against our + // own estimate of the number of chains // FILE LOADED OK - ssm = StructureSelectionManager.getStructureSelectionManager(); MCview.PDBfile pdbFile = ssm.setMapping(sequence, chains, pdbentry .getFile(), AppletFormatAdapter.FILE); - ssm.addStructureViewerListener(this); Vector chains = new Vector(); for (int i = 0; i < pdbFile.chains.size(); i++) { chains - .addElement(((MCview.PDBChain) pdbFile.chains.elementAt(i)).id); + .addElement(new String(pdbFile.id+":"+((MCview.PDBChain) pdbFile.chains.elementAt(i)).id)); } setChainMenuItems(chains); - jmolpopup.updateComputedMenus(); - if (!loadingFromArchive) { viewer - .evalStringQuiet("select backbone;restrict;cartoon;wireframe off;spacefill off"); + .evalStringQuiet("model 0; select backbone;restrict;cartoon;wireframe off;spacefill off"); colourBySequence(ap); } @@ -820,8 +972,23 @@ public class AppJmol extends GStructureViewer implements StructureListener, loadingFromArchive = false; } - else - return; + else { + // 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) + { + ssm.addStructureViewerListener(this); + jmolpopup.updateComputedMenus(); + } } public void sendConsoleEcho(String strEcho) @@ -854,10 +1021,12 @@ public class AppJmol extends GStructureViewer implements StructureListener, public void notifyAtomPicked(int atomIndex, String strInfo, String strData) { - if (strData!=null) + if (strData != null) { - Cache.log.info("Non null pick data string: "+strData+" (other info: '"+strInfo+"' pos "+atomIndex+")"); + Cache.log.info("Non null pick data string: " + strData + + " (other info: '" + strInfo + "' pos " + atomIndex + ")"); } + /* Matcher matcher = pattern.matcher(strInfo); matcher.find(); @@ -867,17 +1036,35 @@ public class AppJmol extends GStructureViewer implements StructureListener, String picked = resnum; + if (chainId != null) picked += (":" + chainId.substring(1, chainId.length())); - - picked = "(("+picked+".CA" + ")|("+picked+".P"+"))"; - +*/ + int chainSeparator = strInfo.indexOf(":"); + int p=0; + if (chainSeparator == -1) + chainSeparator = strInfo.indexOf("."); + + String picked = strInfo.substring(strInfo.indexOf("]") + 1, + chainSeparator); + String mdlString=""; + if ((p=strInfo.indexOf(":")) > -1) + picked += strInfo.substring(p + 1, strInfo + .indexOf(".")); + + if ((p=strInfo.indexOf("/"))> -1) + { + mdlString += strInfo.substring(p, strInfo.indexOf(" #")); + } + picked = "((" + picked + ".CA" + mdlString+")|(" + picked + ".P" + mdlString+"))"; + jmolHistory(false); if (!atomsPicked.contains(picked)) { - if (chainId != null) + // TODO: re-instate chain ID separator dependent labelling for both applet and application +// if (chainId != null) viewer.evalString("select " + picked + ";label %n %r:%c"); - else - viewer.evalString("select " + picked + ";label %n %r"); +// else +// viewer.evalString("select " + picked + ";label %n %r"); atomsPicked.addElement(picked); } else @@ -885,7 +1072,7 @@ public class AppJmol extends GStructureViewer implements StructureListener, viewer.evalString("select " + picked + ";label off"); atomsPicked.removeElement(picked); } - + jmolHistory(true); if (scriptWindow != null) { scriptWindow.sendConsoleMessage(strInfo); @@ -895,9 +1082,10 @@ public class AppJmol extends GStructureViewer implements StructureListener, public void notifyAtomHovered(int atomIndex, String strInfo, String data) { - if (data!=null) + if (data != null) { - Cache.log.info("Non null hover data string: "+data+" (other info: '"+strInfo+"' pos "+atomIndex+")"); + Cache.log.info("Non null hover data string: " + data + + " (other info: '" + strInfo + "' pos " + atomIndex + ")"); } mouseOverStructure(atomIndex, strInfo); } @@ -905,11 +1093,12 @@ public class AppJmol extends GStructureViewer implements StructureListener, @Override public void showUrl(String url) { - try { + try + { jalview.util.BrowserLauncher.openURL(url); } catch (IOException e) { - Cache.log.error("Failed to launch Jmol-associated url "+url,e); + Cache.log.error("Failed to launch Jmol-associated url " + url, e); // TODO: 2.6 : warn user if browser was not configured. } } @@ -1024,39 +1213,44 @@ public class AppJmol extends GStructureViewer implements StructureListener, @Override 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) { - Cache.log.warn("Squashed Jmol callback handler error: ",e); + Cache.log.warn("Squashed Jmol callback handler error: ", e); } } @@ -1075,7 +1269,7 @@ public class AppJmol extends GStructureViewer 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: @@ -1087,8 +1281,9 @@ public class AppJmol extends GStructureViewer implements StructureListener, public void setCallbackFunction(String callbackType, String callbackFunction) { - Cache.log.debug("Ignoring set-callback request to associate "+callbackType+" with function "+callbackFunction); - + Cache.log.debug("Ignoring set-callback request to associate " + + callbackType + " with function " + callbackFunction); + } }