X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fext%2Frbvi%2Fchimera%2FJalviewChimeraBinding.java;h=9b9c239fd8808fb362ad1b2d325308d223c6c7b5;hb=ab43013b7e357b84b4abade0dba949668dfb2a0e;hp=7e72d8f7238abb0f4a3b9d8d87b778c180f57cde;hpb=ae216fceddd8539d20fa5425cdaef3da73aba8f0;p=jalview.git diff --git a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java index 7e72d8f..9b9c239 100644 --- a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java +++ b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java @@ -1,5 +1,5 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2b1) * Copyright (C) 2014 The Jalview Authors * * This file is part of Jalview. @@ -20,7 +20,6 @@ */ package jalview.ext.rbvi.chimera; -import static org.junit.Assert.assertTrue; import jalview.api.AlignmentViewPanel; import jalview.api.FeatureRenderer; import jalview.api.SequenceRenderer; @@ -37,42 +36,32 @@ import jalview.structure.StructureListener; import jalview.structure.StructureMapping; import jalview.structure.StructureSelectionManager; import jalview.structures.models.SequenceStructureBindingModel; +import jalview.util.MessageManager; import java.awt.Color; -import java.awt.Container; import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; import java.io.File; -import java.net.URL; -import java.security.AccessControlException; import java.util.ArrayList; -import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; -import java.util.Hashtable; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Vector; - -import org.jmol.adapter.smarter.SmarterJmolAdapter; -import org.jmol.api.JmolAppConsoleInterface; -import org.jmol.api.JmolSelectionListener; -import org.jmol.api.JmolStatusListener; -import org.jmol.api.JmolViewer; -import org.jmol.constant.EnumCallback; -import org.jmol.popup.JmolPopup; import ext.edu.ucsf.rbvi.strucviz2.ChimeraManager; import ext.edu.ucsf.rbvi.strucviz2.ChimeraModel; import ext.edu.ucsf.rbvi.strucviz2.StructureManager; import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType; -import sun.rmi.runtime.Log; public abstract class JalviewChimeraBinding extends SequenceStructureBindingModel implements StructureListener, SequenceStructureBinding, StructureSelectionManagerProvider { + private static final String PHOSPHORUS = "P"; + + private static final String ALPHACARBON = "CA"; + private StructureManager csm; private ChimeraManager viewer; @@ -85,13 +74,14 @@ public abstract class JalviewChimeraBinding extends private boolean loadingFromArchive = false; /** - * second flag to indicate if the jmol viewer should ignore sequence colouring - * events from the structure manager because the GUI is still setting up + * second flag to indicate if the Chimera viewer should ignore sequence + * colouring events from the structure manager because the GUI is still + * setting up */ private boolean loadingFinished = true; /** - * state flag used to check if the Jmol viewer's paint method can be called + * state flag used to check if the Chimera viewer's paint method can be called */ private boolean finishedInit = false; @@ -109,18 +99,18 @@ public abstract class JalviewChimeraBinding extends /** * when true, try to search the associated datamodel for sequences that are - * associated with any unknown structures in the Jmol view. + * associated with any unknown structures in the Chimera view. */ private boolean associateNewStructs = false; - Vector atomsPicked = new Vector(); + List atomsPicked = new ArrayList(); - public Vector chainNames; + public List chainNames; - Hashtable chainFile; + private Map chainFile; /** - * array of target chains for seuqences - tied to pdbentry and sequence[] + * array of target chains for sequences - tied to pdbentry and sequence[] */ protected String[][] chains; @@ -130,7 +120,7 @@ public abstract class JalviewChimeraBinding extends public String fileLoadingError; - private Map> chimmaps = new HashMap>(); + private Map> chimmaps = new LinkedHashMap>(); private List mdlToFile = new ArrayList(); @@ -152,7 +142,7 @@ public abstract class JalviewChimeraBinding extends try { List oldList = viewer.getModelList(); - viewer.openModel(file, ModelType.PDB_MODEL); + viewer.openModel(file, pe.getId(), ModelType.PDB_MODEL); List newList = viewer.getModelList(); if (oldList.size() < newList.size()) { @@ -164,7 +154,7 @@ public abstract class JalviewChimeraBinding extends chimmaps.put(file, newList); for (ChimeraModel cm : newList) { - while (mdlToFile.size()<1+cm.getModelNumber()) + while (mdlToFile.size() < 1 + cm.getModelNumber()) { mdlToFile.add(new String("")); } @@ -184,7 +174,7 @@ public abstract class JalviewChimeraBinding extends } catch (Error e) { } - // Explicitly map to the filename used by Jmol ; + // Explicitly map to the filename used by Chimera ; // pdbentry[pe].getFile(), protocol); if (ssm != null) @@ -247,13 +237,6 @@ public abstract class JalviewChimeraBinding extends } viewer = new ChimeraManager( csm = new ext.edu.ucsf.rbvi.strucviz2.StructureManager(true)); - /* - * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(), - * "jalviewJmol", ap.av.applet .getDocumentBase(), - * ap.av.applet.getCodeBase(), "", this); - * - * jmolpopup = JmolPopup.newJmolPopup(viewer, true, "Jmol", true); - */ } public JalviewChimeraBinding(StructureSelectionManager ssm, @@ -265,12 +248,13 @@ public abstract class JalviewChimeraBinding extends } /** - * construct a title string for the viewer window based on the data jalview + * Construct a title string for the viewer window based on the data Jalview * knows about * + * @param verbose * @return */ - public String getViewerTitle() + public String getViewerTitle(boolean verbose) { if (sequence == null || pdbentry == null || sequence.length < 1 || pdbentry.length < 1 || sequence[0].length < 1) @@ -279,20 +263,24 @@ public abstract class JalviewChimeraBinding extends } // TODO: give a more informative title when multiple structures are // displayed. - StringBuffer title = new StringBuffer("Chimera view for " - + sequence[0][0].getName() + ":" + pdbentry[0].getId()); + StringBuilder title = new StringBuilder(64); + title.append("Chimera view for " + sequence[0][0].getName() + ":" + + pdbentry[0].getId()); - if (pdbentry[0].getProperty() != null) + if (verbose) { - if (pdbentry[0].getProperty().get("method") != null) + if (pdbentry[0].getProperty() != null) { - title.append(" Method: "); - title.append(pdbentry[0].getProperty().get("method")); - } - if (pdbentry[0].getProperty().get("chains") != null) - { - title.append(" Chain:"); - title.append(pdbentry[0].getProperty().get("chains")); + if (pdbentry[0].getProperty().get("method") != null) + { + title.append(" Method: "); + title.append(pdbentry[0].getProperty().get("method")); + } + if (pdbentry[0].getProperty().get("chains") != null) + { + title.append(" Chain:"); + title.append(pdbentry[0].getProperty().get("chains")); + } } } return title.toString(); @@ -302,47 +290,52 @@ public abstract class JalviewChimeraBinding extends * prepare the view for a given set of models/chains. chainList contains * strings of the form 'pdbfilename:Chaincode' * - * @param chainList + * @param toshow * list of chains to make visible */ - public void centerViewer(Vector chainList) + public void centerViewer(List toshow) { - StringBuffer cmd = new StringBuffer(); - String lbl; + StringBuilder cmd = new StringBuilder(64); int mlength, p; - for (int i = 0, iSize = chainList.size(); i < iSize; i++) + for (String lbl : toshow) { mlength = 0; - lbl = (String) chainList.elementAt(i); do { p = mlength; mlength = lbl.indexOf(":", p); } while (p < mlength && mlength < (lbl.length() - 2)); // TODO: lookup each pdb id and recover proper model number for it. - cmd.append("#" + getModelNum((String) chainFile.get(lbl)) + "." + cmd.append("#" + getModelNum(chainFile.get(lbl)) + "." + lbl.substring(mlength + 1) + " or "); } if (cmd.length() > 0) + { cmd.setLength(cmd.length() - 4); - evalStateCommand("~display #*; ~ribbon #*; ribbon " + cmd + ";focus " - + cmd); + } + String cmdstring = cmd.toString(); + evalStateCommand("~display #*; ~ribbon #*; ribbon " + cmdstring + + ";focus " + cmdstring, false); } - public void closeViewer() + /** + * Close down the Jalview viewer, and (optionally) the associate Chimera + * window. + */ + public void closeViewer(boolean closeChimera) { ssm.removeStructureViewerListener(this, this.getPdbFile()); - // and shut down Chimera - viewer.exitChimera(); - // viewer.evalStringQuiet("zap"); - // viewer.setJmolStatusListener(null); + if (closeChimera) + { + viewer.exitChimera(); + } lastCommand = null; viewer = null; releaseUIResources(); } /** - * called by JalviewJmolbinding after closeViewer is called - release any + * called by JalviewChimerabinding after closeViewer is called - release any * resources and references so they can be garbage collected. */ protected abstract void releaseUIResources(); @@ -350,17 +343,15 @@ public abstract class JalviewChimeraBinding extends public void colourByChain() { colourBySequence = false; - // TODO: colour by chain should colour each chain distinctly across all - // visible models - // TODO: http://issues.jalview.org/browse/JAL-628 - evalStateCommand("select *;color chain"); + evalStateCommand("rainbow chain", false); } public void colourByCharge() { colourBySequence = false; - evalStateCommand("colour *;color white;select ASP,GLU;color red;" - + "select LYS,ARG;color blue;select CYS;color yellow"); + evalStateCommand( + "color white;color red ::ASP;color red ::GLU;color blue ::LYS;color blue ::ARG;color yellow ::CYS", + false); } /** @@ -408,9 +399,9 @@ public abstract class JalviewChimeraBinding extends int[] _refStructure, ColumnSelection[] _hiddenCols) { assert (_alignment.length == _refStructure.length && _alignment.length != _hiddenCols.length); - + StringBuilder allComs = new StringBuilder(128); // Chimera superposition cmd String[] files = getPdbFile(); - // check to see if we are still waiting for Jmol files + // check to see if we are still waiting for Chimera files long starttime = System.currentTimeMillis(); boolean waiting = true; do @@ -441,26 +432,11 @@ public abstract class JalviewChimeraBinding extends if (waiting) { System.err - .println("RUNTIME PROBLEM: Jmol seems to be taking a long time to process all the structures."); + .println("RUNTIME PROBLEM: Chimera seems to be taking a long time to process all the structures."); return; } + refreshPdbEntries(); StringBuffer selectioncom = new StringBuffer(); - // In principle - nSeconds specifies the speed of animation for each - // superposition - but is seems to behave weirdly, so we don't specify it. - String nSeconds = " "; - if (files.length > 10) - { - nSeconds = " 0.00001 "; - } - else - { - nSeconds = " " + (2.0 / files.length) + " "; - // if (nSeconds).substring(0,5)+" "; - } - // see JAL-1345 - should really automatically turn off the animation for - // large numbers of structures, but Jmol doesn't seem to allow that. - nSeconds = " "; - // union of all aligned positions are collected together. for (int a = 0; a < _alignment.length; a++) { int refStructure = _refStructure[a]; @@ -469,9 +445,9 @@ public abstract class JalviewChimeraBinding extends if (a > 0 && selectioncom.length() > 0 && !selectioncom.substring(selectioncom.length() - 1).equals( - "|")) + " ")) { - selectioncom.append("|"); + selectioncom.append(" "); } // process this alignment if (refStructure >= files.length) @@ -484,7 +460,6 @@ public abstract class JalviewChimeraBinding extends { refStructure = -1; } - StringBuffer command = new StringBuffer(); boolean matched[] = new boolean[alignment.getWidth()]; for (int m = 0; m < matched.length; m++) @@ -495,9 +470,9 @@ public abstract class JalviewChimeraBinding extends int commonrpositions[][] = new int[files.length][alignment.getWidth()]; String isel[] = new String[files.length]; - // reference structure - all others are superposed in it String[] targetC = new String[files.length]; String[] chainNames = new String[files.length]; + String[] atomSpec = new String[files.length]; for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++) { StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]); @@ -505,8 +480,7 @@ public abstract class JalviewChimeraBinding extends // Jmol callback has completed. if (mapping == null || mapping.length < 1) { - throw new Error( - "Implementation error - Jmol seems to be still working on getting its data - report at http://issues.jalview.org/browse/JAL-1016"); + throw new Error(MessageManager.getString("error.implementation_error_chimera_getting_data")); } int lastPos = -1; for (int s = 0; s < sequence[pdbfnum].length; s++) @@ -553,7 +527,7 @@ public abstract class JalviewChimeraBinding extends commonrpositions[pdbfnum][r] = pos; } // create model selection suffix - isel[pdbfnum] = "/" + (pdbfnum + 1) + ".1"; + isel[pdbfnum] = "#" + pdbfnum; if (mapping[m].getChain() == null || mapping[m].getChain().trim().length() == 0) { @@ -561,10 +535,11 @@ public abstract class JalviewChimeraBinding extends } else { - targetC[pdbfnum] = ":" + mapping[m].getChain(); + targetC[pdbfnum] = "." + mapping[m].getChain(); } chainNames[pdbfnum] = mapping[m].getPdbId() + targetC[pdbfnum]; + atomSpec[pdbfnum] = asp.getRNA() != null ? PHOSPHORUS : ALPHACARBON; // move on to next pdb file s = sequence[pdbfnum].length; break; @@ -581,6 +556,7 @@ public abstract class JalviewChimeraBinding extends String[] selcom = new String[files.length]; int nmatched = 0; + String sep = ""; // generate select statements to select regions to superimpose structures { for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++) @@ -589,7 +565,6 @@ public abstract class JalviewChimeraBinding extends int lpos = -1; boolean run = false; StringBuffer molsel = new StringBuffer(); - molsel.append("{"); for (int r = 0; r < matched.length; r++) { if (matched[r]) @@ -603,10 +578,9 @@ public abstract class JalviewChimeraBinding extends // discontinuity if (lpos != -1) { - molsel.append(lpos); + molsel.append((run ? "" : ":") + lpos); molsel.append(chainCd); - // molsel.append("} {"); - molsel.append("|"); + molsel.append(","); } } else @@ -615,7 +589,7 @@ public abstract class JalviewChimeraBinding extends if (!run) { // at the beginning, so add dash - molsel.append(lpos); + molsel.append(":" + lpos); molsel.append("-"); } run = true; @@ -627,22 +601,19 @@ public abstract class JalviewChimeraBinding extends // add final selection phrase if (lpos != -1) { - molsel.append(lpos); + molsel.append((run ? "" : ":") + lpos); molsel.append(chainCd); - molsel.append("}"); + // molsel.append(""); } if (molsel.length() > 1) { selcom[pdbfnum] = molsel.toString(); - selectioncom.append("(("); - selectioncom.append(selcom[pdbfnum].substring(1, - selcom[pdbfnum].length() - 1)); - selectioncom.append(" )& "); - selectioncom.append(pdbfnum + 1); - selectioncom.append(".1)"); + selectioncom.append("#" + pdbfnum); + selectioncom.append(selcom[pdbfnum]); + selectioncom.append(" "); if (pdbfnum < files.length - 1) { - selectioncom.append("|"); + selectioncom.append("| "); } } else @@ -651,6 +622,7 @@ public abstract class JalviewChimeraBinding extends } } } + StringBuilder command = new StringBuilder(256); for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++) { if (pdbfnum == refStructure || selcom[pdbfnum] == null @@ -658,36 +630,37 @@ public abstract class JalviewChimeraBinding extends { continue; } - command.append("echo "); - command.append("\"Superposing ("); - command.append(chainNames[pdbfnum]); - command.append(") against reference ("); - command.append(chainNames[refStructure]); - command.append(")\";\ncompare " + nSeconds); - command.append("{"); - command.append(1 + pdbfnum); - command.append(".1} {"); - command.append(1 + refStructure); - command.append(".1} SUBSET {*.CA | *.P} ATOMS "); - - // form the matched pair strings - String sep = ""; - for (int s = 0; s < 2; s++) + if (command.length() > 0) { - command.append(selcom[(s == 0 ? pdbfnum : refStructure)]); + command.append(";"); } - command.append(" ROTATE TRANSLATE;\n"); + + /* + * Form Chimera match command, from the 'new' structure to the + * 'reference' structure e.g. (residues 1-91, chain B/A, alphacarbons): + * + * match #1:1-91.B@CA #0:1-91.A@CA + * + * @see + * https://www.cgl.ucsf.edu/chimera/docs/UsersGuide/midas/match.html + */ + command.append("match #" + pdbfnum /* +".1" */); + // TODO: handle sub-models + command.append(selcom[pdbfnum]); + command.append("@" + atomSpec[pdbfnum]); + command.append(" #" + refStructure /* +".1" */); + command.append(selcom[refStructure]); + command.append("@" + atomSpec[refStructure]); } if (selectioncom.length() > 0) { + // TODO remove debug output System.out.println("Select regions:\n" + selectioncom.toString()); - evalStateCommand("select *; cartoons off; backbone; select (" - + selectioncom.toString() + "); cartoons; "); - // selcom.append("; ribbons; "); System.out .println("Superimpose command(s):\n" + command.toString()); - - evalStateCommand(command.toString()); + allComs.append("~display all; chain @CA|P; ribbon " + + selectioncom.toString() + ";"+command.toString()); + // selcom.append("; ribbons; "); } } if (selectioncom.length() > 0) @@ -697,10 +670,12 @@ public abstract class JalviewChimeraBinding extends selectioncom.setLength(selectioncom.length() - 1); } System.out.println("Select regions:\n" + selectioncom.toString()); - evalStateCommand("select *; cartoons off; backbone; select (" - + selectioncom.toString() + "); cartoons; "); + allComs.append("; ~display all; chain @CA|P; ribbon " + + selectioncom.toString() + "; focus"); // evalStateCommand("select *; backbone; select "+selcom.toString()+"; cartoons; center "+selcom.toString()); + evalStateCommand(allComs.toString(), true /* false */); } + } private void checkLaunched() @@ -715,18 +690,51 @@ public abstract class JalviewChimeraBinding extends } } - public void evalStateCommand(String command) + /** + * Answers true if the Chimera process is still running, false if ended or not + * started. + * + * @return + */ + public boolean isChimeraRunning() + { + return viewer.isChimeraLaunched(); + } + + /** + * Send a command to Chimera, and optionally log any responses. + * + * @param command + * @param logResponse + */ + public void evalStateCommand(final String command, boolean logResponse) { viewerCommandHistory(false); checkLaunched(); if (lastCommand == null || !lastCommand.equals(command)) { - - lastReply = viewer.sendChimeraCommand(command, true); - if (debug) - { - log("Response from command ('" + command + "') was:\n" + lastReply); - } +// Thread t = new Thread(new Runnable() +// { +// @Override +// public void run() +// { + // trim command or it may never find a match in the replyLog!! + lastReply = viewer.sendChimeraCommand(command.trim(), logResponse); + if (debug && logResponse) + { + log("Response from command ('" + command + "') was:\n" + + lastReply); + } +// } +// }); + // TODO - use j7/8 thread management +// try +// { +// t.join(); +// } catch (InterruptedException foo) +// { +// } +// ; } viewerCommandHistory(true); lastCommand = command; @@ -741,7 +749,9 @@ public abstract class JalviewChimeraBinding extends jalview.api.AlignmentViewPanel alignmentv) { if (!colourBySequence || !loadingFinished) + { return; + } if (ssm == null) { return; @@ -760,10 +770,25 @@ public abstract class JalviewChimeraBinding extends for (jalview.structure.StructureMappingcommandSet cpdbbyseq : ChimeraCommands .getColourBySequenceCommand(ssm, files, sequence, sr, fr, alignment)) + { for (String cbyseq : cpdbbyseq.commands) { - evalStateCommand(cbyseq); + waitForChimera(); + evalStateCommand(cbyseq, false); + waitForChimera(); } + } + } + + private void waitForChimera() + { + while (viewer != null && viewer.isBusy()) + { + try { + Thread.sleep(15); + } catch (InterruptedException q) + {} + } } public boolean isColourBySequence() @@ -776,25 +801,6 @@ public abstract class JalviewChimeraBinding extends this.colourBySequence = colourBySequence; } - public void createImage(String file, String type, int quality) - { - System.out.println("JMOL CREATE IMAGE"); - } - - public String createImage(String fileName, String type, - Object textOrBytes, int quality) - { - System.out.println("JMOL CREATE IMAGE"); - return null; - } - - public String eval(String strEval) - { - // System.out.println(strEval); - // "# 'eval' is implemented only for the applet."; - return null; - } - // End StructureListener // ////////////////////////// @@ -813,7 +819,9 @@ public abstract class JalviewChimeraBinding extends String pdbfile) { if (getModelNum(pdbfile) < 0) + { return null; + } log("get model / residue colour attribute unimplemented"); return null; } @@ -846,7 +854,9 @@ public abstract class JalviewChimeraBinding extends for (int i = 0; i < mfn.length; i++) { if (mfn[i].equalsIgnoreCase(modelFileName)) + { return i; + } } return -1; } @@ -866,18 +876,18 @@ public abstract class JalviewChimeraBinding extends { return new String[0]; } -// if (modelFileNames == null) -// { -// Collection chimodels = viewer.getChimeraModels(); -// _modelFileNameMap = new int[chimodels.size()]; -// int j = 0; -// for (ChimeraModel chimodel : chimodels) -// { -// String mdlName = chimodel.getModelName(); -// } -// modelFileNames = new String[j]; -// // System.arraycopy(mset, 0, modelFileNames, 0, j); -// } + // if (modelFileNames == null) + // { + // Collection chimodels = viewer.getChimeraModels(); + // _modelFileNameMap = new int[chimodels.size()]; + // int j = 0; + // for (ChimeraModel chimodel : chimodels) + // { + // String mdlName = chimodel.getModelName(); + // } + // modelFileNames = new String[j]; + // // System.arraycopy(mset, 0, modelFileNames, 0, j); + // } return chimmaps.keySet().toArray( modelFileNames = new String[chimmaps.size()]); @@ -913,20 +923,20 @@ public abstract class JalviewChimeraBinding extends int mdlNum = cms.get(0).getModelNumber(); viewerCommandHistory(false); - viewer.stopListening(); + // viewer.stopListening(); if (resetLastRes.length() > 0) { - viewer.sendChimeraCommand(resetLastRes.toString(), false); + eval.setLength(0); + eval.append(resetLastRes.toString() + ";"); } - eval.setLength(0); eval.append("display "); // +modelNum resetLastRes.setLength(0); resetLastRes.append("~display "); { eval.append(" #" + (mdlNum)); - resetLastRes.append("#" + (mdlNum)); + resetLastRes.append(" #" + (mdlNum)); } // complete select string @@ -937,18 +947,14 @@ public abstract class JalviewChimeraBinding extends eval.append("." + chain); resetLastRes.append("." + chain); } - eval.append(eval.toString()); - - resetLastRes.append(resetLastRes.toString() - ); - + viewer.sendChimeraCommand(eval.toString(), false); viewerCommandHistory(true); - viewer.startListening(); + // viewer.startListening(); } } - boolean debug = true; + boolean debug = false; private void log(String message) { @@ -957,8 +963,8 @@ public abstract class JalviewChimeraBinding extends private void viewerCommandHistory(boolean enable) { - log("(Not yet implemented) History " - + ((debug || enable) ? "on" : "off")); + // log("(Not yet implemented) History " + // + ((debug || enable) ? "on" : "off")); } public void loadInline(String string) @@ -1009,8 +1015,10 @@ public abstract class JalviewChimeraBinding extends String chainId; if (strInfo.indexOf(":") > -1) + { chainId = strInfo.substring(strInfo.indexOf(":") + 1, strInfo.indexOf(".")); + } else { chainId = " "; @@ -1048,7 +1056,9 @@ public abstract class JalviewChimeraBinding extends ; } if (lastMessage == null || !lastMessage.equals(strInfo)) + { ssm.mouseOverStructure(pdbResNum, chainId, pdbfilename); + } lastMessage = strInfo; } @@ -1067,13 +1077,17 @@ public abstract class JalviewChimeraBinding extends 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) { @@ -1086,12 +1100,12 @@ public abstract class JalviewChimeraBinding extends if (!atomsPicked.contains(picked)) { viewer.select(picked); - atomsPicked.addElement(picked); + atomsPicked.add(picked); } else { viewer.select("not " + picked); - atomsPicked.removeElement(picked); + atomsPicked.remove(picked); } viewerCommandHistory(true); // TODO: in application this happens @@ -1106,7 +1120,7 @@ public abstract class JalviewChimeraBinding extends // incremented every time a load notification is successfully handled - // lightweight mechanism for other threads to detect when they can start - // referrring to new structures. + // referring to new structures. private long loadNotifiesHandled = 0; public long getLoadNotifiesHandled() @@ -1132,8 +1146,8 @@ public abstract class JalviewChimeraBinding extends fileLoadingError = null; String[] oldmodels = modelFileNames; modelFileNames = null; - chainNames = new Vector(); - chainFile = new Hashtable(); + chainNames = new ArrayList(); + chainFile = new HashMap(); boolean notifyLoaded = false; String[] modelfilenames = getPdbFile(); // first check if we've lost any structures @@ -1194,49 +1208,43 @@ public abstract class JalviewChimeraBinding extends colourBySequence = false; if (cs == null) + { return; + } String res; int index; Color col; + // Chimera expects RBG values in the range 0-1 + final double normalise = 255D; viewerCommandHistory(false); // TODO: Switch between nucleotide or aa selection expressions Enumeration en = ResidueProperties.aa3Hash.keys(); - StringBuffer command = new StringBuffer("select *;color white;"); + StringBuilder command = new StringBuilder(128); + command.append("color white;"); while (en.hasMoreElements()) { res = en.nextElement().toString(); index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue(); if (index > 20) + { continue; + } col = cs.findColour(ResidueProperties.aa[index].charAt(0)); - // TODO: need colour string function and res selection here - command.append("select " + res + ";color[" + col.getRed() + "," - + col.getGreen() + "," + col.getBlue() + "];"); + command.append("color " + col.getRed() / normalise + "," + + col.getGreen() / normalise + "," + col.getBlue() + / normalise + " ::" + res + ";"); } - evalStateCommand(command.toString()); + evalStateCommand(command.toString(),false); viewerCommandHistory(true); } - public void showHelp() - { - // chimera help - showUrl("http://jmol.sourceforge.net/docs/JmolUserGuide/", "jmolHelp"); - } - - /** - * open the URL somehow - * - * @param target - */ - public abstract void showUrl(String url, String target); - /** - * called when the binding thinks the UI needs to be refreshed after a Jmol + * called when the binding thinks the UI needs to be refreshed after a Chimera * state change. this could be because structures were loaded, or because an - * error has occured. + * error has occurred. */ public abstract void refreshGUI(); @@ -1265,8 +1273,8 @@ public abstract class JalviewChimeraBinding extends /** * - * @return true if Jmol is still restoring state or loading is still going on - * (see setFinsihedLoadingFromArchive) + * @return true if Chimeral is still restoring state or loading is still going + * on (see setFinsihedLoadingFromArchive) */ public boolean isLoadingFromArchive() { @@ -1284,13 +1292,22 @@ public abstract class JalviewChimeraBinding extends loadingFinished = finishedLoading; } - public void setBackgroundColour(java.awt.Color col) + /** + * Send the Chimera 'background solid " command. + * + * @see https + * ://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/background + * .html + * @param col + */ + public void setBackgroundColour(Color col) { viewerCommandHistory(false); - // todo set background colour - viewer.sendChimeraCommand( - "background [" + col.getRed() + "," + col.getGreen() + "," - + col.getBlue() + "];", false); + double normalise = 255D; + final String command = "background solid " + col.getRed() / normalise + "," + + col.getGreen() / normalise + "," + col.getBlue() + / normalise + ";"; + viewer.sendChimeraCommand(command, false); viewerCommandHistory(true); } @@ -1302,21 +1319,20 @@ public abstract class JalviewChimeraBinding extends public synchronized PDBEntry[] addSequenceAndChain(PDBEntry[] pdbe, SequenceI[][] seq, String[][] chns) { - int pe = -1; - Vector v = new Vector(); - Vector rtn = new Vector(); + List v = new ArrayList(); + List rtn = new ArrayList(); for (int i = 0; i < pdbentry.length; i++) { - v.addElement(pdbentry[i]); + v.add(pdbentry[i]); } for (int i = 0; i < pdbe.length; i++) { int r = v.indexOf(pdbe[i]); if (r == -1 || r >= pdbentry.length) { - rtn.addElement(new int[] + rtn.add(new int[] { v.size(), i }); - v.addElement(pdbe[i]); + v.add(pdbe[i]); } else { @@ -1324,12 +1340,11 @@ public abstract class JalviewChimeraBinding extends addSequenceAndChain(r, seq[i], chns[i]); } } - pdbe = new PDBEntry[v.size()]; - v.copyInto(pdbe); + pdbe = v.toArray(new PDBEntry[v.size()]); pdbentry = pdbe; if (rtn.size() > 0) { - // expand the tied seuqence[] and string[] arrays + // expand the tied sequence[] and string[] arrays SequenceI[][] sqs = new SequenceI[pdbentry.length][]; String[][] sch = new String[pdbentry.length][]; System.arraycopy(sequence, 0, sqs, 0, sequence.length); @@ -1339,7 +1354,7 @@ public abstract class JalviewChimeraBinding extends pdbe = new PDBEntry[rtn.size()]; for (int r = 0; r < pdbe.length; r++) { - int[] stri = ((int[]) rtn.elementAt(r)); + int[] stri = (rtn.get(r)); // record the pdb file as a new addition pdbe[r] = pdbentry[stri[0]]; // and add the new sequence/chain entries @@ -1353,9 +1368,14 @@ public abstract class JalviewChimeraBinding extends return pdbe; } + /** + * Adds sequences to the pe'th pdbentry's sequence set. + * + * @param pe + * @param seq + */ public void addSequence(int pe, SequenceI[] seq) { - // add sequences to the pe'th pdbentry's seuqence set. addSequenceAndChain(pe, seq, null); } @@ -1363,13 +1383,14 @@ public abstract class JalviewChimeraBinding extends { if (pe < 0 || pe >= pdbentry.length) { - throw new Error( - "Implementation error - no corresponding pdbentry (for index " - + pe + ") to add sequences mappings to"); + throw new Error(MessageManager.formatMessage( + "error.implementation_error_no_pdbentry_from_index", + new Object[] + { Integer.valueOf(pe).toString() })); } final String nullChain = "TheNullChain"; - Vector s = new Vector(); - Vector c = new Vector(); + List s = new ArrayList(); + List c = new ArrayList(); if (chains == null) { chains = new String[pdbentry.length][]; @@ -1378,23 +1399,23 @@ public abstract class JalviewChimeraBinding extends { for (int i = 0; i < sequence[pe].length; i++) { - s.addElement(sequence[pe][i]); + s.add(sequence[pe][i]); if (chains[pe] != null) { if (i < chains[pe].length) { - c.addElement(chains[pe][i]); + c.add(chains[pe][i]); } else { - c.addElement(nullChain); + c.add(nullChain); } } else { if (tchain != null && tchain.length > 0) { - c.addElement(nullChain); + c.add(nullChain); } } } @@ -1403,20 +1424,18 @@ public abstract class JalviewChimeraBinding extends { if (!s.contains(seq[i])) { - s.addElement(seq[i]); + s.add(seq[i]); if (tchain != null && i < tchain.length) { - c.addElement(tchain[i] == null ? nullChain : tchain[i]); + c.add(tchain[i] == null ? nullChain : tchain[i]); } } } - SequenceI[] tmp = new SequenceI[s.size()]; - s.copyInto(tmp); + SequenceI[] tmp = s.toArray(new SequenceI[s.size()]); sequence[pe] = tmp; if (c.size() > 0) { - String[] tch = new String[c.size()]; - c.copyInto(tch); + String[] tch = c.toArray(new String[c.size()]); for (int i = 0; i < tch.length; i++) { if (tch[i] == nullChain)