X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fext%2Fedu%2Fucsf%2Frbvi%2Fstrucviz2%2FChimeraManager.java;h=2e5dbeb19d4fb9bfdce8d648918f5d20f78a9fa1;hb=42f7bb953f9562f9ff80f0d3c833a0b364f399a2;hp=a76c7e0fe69e2f6be247a716b6c40e26dec2ed1c;hpb=81316c6cc11e29c893d55e87ebd16d9ecd09c1f3;p=jalview.git diff --git a/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java b/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java index a76c7e0..2e5dbeb 100644 --- a/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java +++ b/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java @@ -27,15 +27,9 @@ import ext.edu.ucsf.rbvi.strucviz2.port.ListenerThreads; */ public class ChimeraManager { - private static final boolean debug = true; + private static final boolean debug = false; - /* - * true: use REST API (recommended), false: use stdout/stdin (deprecated) - */ - private static final boolean USE_REST = true; - - // Port number for Chimera REST service - private int restPort; + private int chimeraRestPort; private Process chimera; @@ -183,7 +177,7 @@ public class ChimeraManager ModelType type) { logger.info("chimera open " + modelPath); - stopListening(); + // stopListening(); List response = null; // TODO: [Optional] Handle modbase models if (type == ModelType.MODBASE_MODEL) @@ -203,72 +197,21 @@ public class ChimeraManager logger.warn("Could not open " + modelPath); return null; } - List models = new ArrayList(); - int[] modelNumbers = null; - if (type == ModelType.PDB_MODEL) - { - for (String line : response) - { - if (line.startsWith("#")) - { - modelNumbers = ChimUtils.parseOpenedModelNumber(line); - if (modelNumbers != null) - { - int modelNumber = ChimUtils.makeModelKey(modelNumbers[0], - modelNumbers[1]); - if (currentModelsMap.containsKey(modelNumber)) - { - continue; - } - ChimeraModel newModel = new ChimeraModel(modelName, type, - modelNumbers[0], modelNumbers[1]); - currentModelsMap.put(modelNumber, newModel); - models.add(newModel); - // patch for Jalview - set model name in Chimera - sendChimeraCommand("setattr M name " + modelName + " #" - + modelNumbers[0], false); - // end patch for Jalview - modelNumbers = null; - } - } - } - } - else - { - // TODO: [Optional] Open smiles from file would fail. Do we need it? - // If parsing fails, iterate over all open models to get the right one - List openModels = getModelList(); - for (ChimeraModel openModel : openModels) - { - String openModelName = openModel.getModelName(); - if (openModelName.endsWith("...")) - { - openModelName = openModelName.substring(0, - openModelName.length() - 3); - } - if (modelPath.startsWith(openModelName)) - { - openModel.setModelName(modelPath); - int modelNumber = ChimUtils - .makeModelKey(openModel.getModelNumber(), - openModel.getSubModelNumber()); - if (!currentModelsMap.containsKey(modelNumber)) - { - currentModelsMap.put(modelNumber, openModel); - models.add(openModel); - } - } - } - } - + List chimeraModels = getModelList(); // assign color and residues to open models - for (ChimeraModel newModel : models) - { + for (ChimeraModel chimeraModel : chimeraModels) + { + // // patch for Jalview - set model name in Chimera + // // TODO: find a variant that works for sub-models + chimeraModel.setModelName(modelName); + sendChimeraCommand( + "setattr M name " + modelName + " #" + + chimeraModel.getModelNumber(), false); // get model color - Color modelColor = getModelColor(newModel); + Color modelColor = getModelColor(chimeraModel); if (modelColor != null) { - newModel.setModelColor(modelColor); + chimeraModel.setModelColor(modelColor); } // Get our properties (default color scheme, etc.) @@ -278,13 +221,13 @@ public class ChimeraManager // Create the information we need for the navigator if (type != ModelType.SMILES) { - addResidues(newModel); + addResidues(chimeraModel); } } sendChimeraCommand("focus", false); - startListening(); - return models; + // startListening(); // see ChimeraListener + return chimeraModels; } /** @@ -304,13 +247,12 @@ public class ChimeraManager // TODO: [Optional] Convert path to name in a better way if (modelPath.lastIndexOf(File.separator) > 0) { - modelName = modelPath.substring(modelPath - .lastIndexOf(File.separator) + 1); + modelName = modelPath + .substring(modelPath.lastIndexOf(File.separator) + 1); } else if (modelPath.lastIndexOf("/") > 0) { - modelName = modelPath - .substring(modelPath.lastIndexOf("/") + 1); + modelName = modelPath.substring(modelPath.lastIndexOf("/") + 1); } return modelName; } @@ -341,12 +283,24 @@ public class ChimeraManager public void startListening() { - sendChimeraCommand("listen start models; listen start select", false); + sendChimeraCommand("listen start models; listen start selection", false); } public void stopListening() { - sendChimeraCommand("listen stop models; listen stop select", false); + sendChimeraCommand("listen stop models ; listen stop selection ", false); + } + + /** + * Tell Chimera we are listening on the given URI + * + * @param uri + */ + public void startListening(String uri) + { + sendChimeraCommand("listen start models url " + uri + + ";listen start select prefix SelectionChanged url " + uri, + false); } /** @@ -357,8 +311,8 @@ public class ChimeraManager */ public void select(String command) { - sendChimeraCommand("listen stop select; " + command - + "; listen start select", false); + sendChimeraCommand("listen stop selection; " + command + + "; listen start selection", false); } public void focus() @@ -370,11 +324,7 @@ public class ChimeraManager { chimera = null; currentModelsMap.clear(); - if (!USE_REST) - { - chimeraListenerThread.requestStop(); - chimeraListenerThread = null; - } + this.chimeraRestPort = 0; structureManager.clearOnChimeraExit(); } @@ -413,6 +363,12 @@ public class ChimeraManager return selectedModelsMap; } + /** + * Sends a 'list selection level residue' command to Chimera and returns the + * list of selected atomspecs + * + * @return + */ public List getSelectedResidueSpecs() { List selectedResidues = new ArrayList(); @@ -520,6 +476,14 @@ public class ChimeraManager return launched; } + /** + * Launch Chimera, unless an instance linked to this object is already + * running. Returns true if chimera is successfully launched, or already + * running, else false. + * + * @param chimeraPaths + * @return + */ public boolean launchChimera(List chimeraPaths) { // Do nothing if Chimera is already launched @@ -535,6 +499,8 @@ public class ChimeraManager for (String chimeraPath : chimeraPaths) { File path = new File(chimeraPath); + // uncomment the next line to simulate Chimera not installed + // path = new File(chimeraPath + "x"); if (!path.canExecute()) { error += "File '" + path + "' does not exist.\n"; @@ -544,14 +510,14 @@ public class ChimeraManager { List args = new ArrayList(); args.add(chimeraPath); + // shows Chimera output window but suppresses REST responses: + // args.add("--debug"); args.add("--start"); - args.add(USE_REST ? "RESTServer" : "ReadStdin"); + args.add("RESTServer"); ProcessBuilder pb = new ProcessBuilder(args); chimera = pb.start(); error = ""; workingPath = chimeraPath; - logger.info("Starting " + chimeraPath + " with " - + (USE_REST ? "REST API" : "stdin/stdout")); break; } catch (Exception e) { @@ -562,23 +528,15 @@ public class ChimeraManager // If no error, then Chimera was launched successfully if (error.length() == 0) { - if (USE_REST) - { - this.restPort = getPortNumber(); - } - else - { - // Initialize the listener threads - chimeraListenerThread = new ListenerThreads(chimera, - structureManager); - chimeraListenerThread.start(); - } + this.chimeraRestPort = getPortNumber(); + System.out.println("Chimera REST API started on port " + + chimeraRestPort); // structureManager.initChimTable(); structureManager.setChimeraPathProperty(workingPath); // TODO: [Optional] Check Chimera version and show a warning if below 1.8 // Ask Chimera to give us updates - startListening(); - return true; + // startListening(); // later - see ChimeraListener + return (chimeraRestPort > 0); } // Tell the user that Chimera could not be started because of an error @@ -595,20 +553,29 @@ public class ChimeraManager InputStream readChan = chimera.getInputStream(); BufferedReader lineReader = new BufferedReader(new InputStreamReader( readChan)); - String response = null; + StringBuilder responses = new StringBuilder(); try { - // expect: REST server on host 127.0.0.1 port port_number - response = lineReader.readLine(); - String [] tokens = response.split(" "); - if (tokens.length == 7 && "port".equals(tokens[5])) { - port = Integer.parseInt(tokens[6]); - logger.info("Chimera REST service listening on port " + restPort); + String response = lineReader.readLine(); + while (response != null) + { + responses.append("\n" + response); + // expect: REST server on host 127.0.0.1 port port_number + if (response.startsWith("REST server")) + { + String[] tokens = response.split(" "); + if (tokens.length == 7 && "port".equals(tokens[5])) + { + port = Integer.parseInt(tokens[6]); + break; + } + } + response = lineReader.readLine(); } } catch (Exception e) { - logger.error("Failed to get REST port number from " + response + ": " - + e.getMessage()); + logger.error("Failed to get REST port number from " + responses + + ": " + e.getMessage()); } finally { try @@ -618,6 +585,13 @@ public class ChimeraManager { } } + if (port == 0) + { + System.err + .println("Failed to start Chimera with REST service, response was: " + + responses); + } + logger.info("Chimera REST service listening on port " + chimeraRestPort); return port; } @@ -746,6 +720,7 @@ public class ChimeraManager */ public List sendChimeraCommand(String command, boolean reply) { + // System.out.println("chimeradebug>> " + command); if (!isChimeraLaunched() || command == null || "".equals(command.trim())) { @@ -760,22 +735,17 @@ public class ChimeraManager } catch (InterruptedException q) { } - ; } busy = true; long startTime = System.currentTimeMillis(); try { - if (USE_REST) - { - return sendRestCommand(command); - } - else - { - return sendStdinCommand(command, reply); - } + return sendRestCommand(command); } finally { + /* + * Make sure busy flag is reset come what may! + */ busy = false; if (debug) { @@ -795,23 +765,24 @@ public class ChimeraManager */ protected List sendRestCommand(String command) { - // TODO start a separate thread to do this so we don't block? - String restUrl = "http://127.0.0.1:" + this.restPort + "/run"; + String restUrl = "http://127.0.0.1:" + this.chimeraRestPort + "/run"; List commands = new ArrayList(1); commands.add(new BasicNameValuePair("command", command)); List reply = new ArrayList(); BufferedReader response = null; - try { - response = HttpClientUtils.doHttpUrlPost(restUrl, - commands); + try + { + response = HttpClientUtils + .doHttpUrlPost(restUrl, commands, 100, 5000); String line = ""; - while ((line = response.readLine()) != null) { + while ((line = response.readLine()) != null) + { reply.add(line); } } catch (Exception e) { - logger.error("REST call " + command + " failed: " + e.getMessage()); + logger.error("REST call '" + command + "' failed: " + e.getMessage()); } finally { if (response != null) @@ -870,5 +841,4 @@ public class ChimeraManager { return busy; } - }