X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fext%2Fedu%2Fucsf%2Frbvi%2Fstrucviz2%2FChimeraManager.java;h=710ca95b01d0bc99097024a7e7056b8734d35c89;hb=e739c2824d4d6a93c3e0f255780259c7daf2dc21;hp=85ae718861cb8b967ee7fac9fe48b0f9bd32b244;hpb=abd0918cc633b946cfea588ef4b4d666edf9fc8b;p=jalview.git diff --git a/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java b/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java index 85ae718..710ca95 100644 --- a/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java +++ b/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java @@ -40,6 +40,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -83,7 +84,7 @@ public class ChimeraManager this.structureManager = structureManager; chimera = null; chimeraListenerThread = null; - currentModelsMap = new HashMap(); + currentModelsMap = new HashMap<>(); } @@ -98,7 +99,7 @@ public class ChimeraManager public List getChimeraModels(String modelName, ModelType modelType) { - List models = new ArrayList(); + List models = new ArrayList<>(); for (ChimeraModel model : currentModelsMap.values()) { if (modelName.equals(model.getModelName()) @@ -112,7 +113,7 @@ public class ChimeraManager public Map> getChimeraModelsMap() { - Map> models = new HashMap>(); + Map> models = new HashMap<>(); for (ChimeraModel model : currentModelsMap.values()) { String modelName = model.getModelName(); @@ -253,7 +254,7 @@ public class ChimeraManager for (ChimeraModel chimeraModel : modelList) { // get model color - Color modelColor = getModelColor(chimeraModel); + Color modelColor = isChimeraX() ? null : getModelColor(chimeraModel); if (modelColor != null) { chimeraModel.setModelColor(modelColor); @@ -264,7 +265,7 @@ public class ChimeraManager // chimeraSend("repr stick "+newModel.toSpec()); // Create the information we need for the navigator - if (type != ModelType.SMILES) + if (type != ModelType.SMILES && !isChimeraX()) { addResidues(chimeraModel); } @@ -333,7 +334,11 @@ public class ChimeraManager public void stopListening() { - sendChimeraCommand("listen stop models ; listen stop selection ", false); + // TODO send this command when viewer connection is closed in Jalview + String command = isChimeraX + ? "info notify stop models jalview; info notify stop selection jalview" + : "listen stop models ; listen stop selection "; + sendChimeraCommand(command, false); } /** @@ -343,9 +348,23 @@ public class ChimeraManager */ public void startListening(String uri) { - sendChimeraCommand("listen start models url " + uri - + ";listen start select prefix SelectionChanged url " + uri, - false); + /* + * listen for model changes + */ + String command = isChimeraX + ? ("info notify start models prefix ModelChanged jalview url " + + uri) + : ("listen start models url " + uri); + sendChimeraCommand(command, false); + + /* + * listen for selection changes + */ + command = isChimeraX + ? ("info notify start selection jalview prefix SelectionChanged url " + + uri) + : ("listen start select prefix SelectionChanged url " + uri); + sendChimeraCommand(command, false); } /** @@ -393,7 +412,7 @@ public class ChimeraManager public Map getSelectedModels() { - Map selectedModelsMap = new HashMap(); + Map selectedModelsMap = new HashMap<>(); List chimeraReply = sendChimeraCommand( "list selection level molecule", true); if (chimeraReply != null) @@ -418,20 +437,35 @@ public class ChimeraManager */ public List getSelectedResidueSpecs() { - List selectedResidues = new ArrayList(); - List chimeraReply = sendChimeraCommand( - "list selection level residue", true); + List selectedResidues = new ArrayList<>(); + + /* + * skip for now if ChimeraX - request times out + */ + if (isChimeraX) + { + // return selectedResidues; + } + + // in fact 'listinfo' (undocumented) works in ChimeraX + String command = (isChimeraX + ? "view" /*"info selection level residue" */ + : "list selection level residue"); + List chimeraReply = sendChimeraCommand(command, true); if (chimeraReply != null) { /* - * expect 0, 1 or more lines of the format + * expect 0, 1 or more lines of the format either + * Chimera: * residue id #0:43.A type GLY - * where we are only interested in the atomspec #0.43.A + * ChimeraX: + * residue id /A:89 name THR index 88 + * We are only interested in the atomspec (third token of the reply) */ for (String inputLine : chimeraReply) { String[] inputLineParts = inputLine.split("\\s+"); - if (inputLineParts.length == 5) + if (inputLineParts.length >= 5) { selectedResidues.add(inputLineParts[2]); } @@ -471,15 +505,22 @@ public class ChimeraManager // TODO: [Optional] Handle smiles names in a better way in Chimera? public List getModelList() { - List modelList = new ArrayList(); - List list = sendChimeraCommand("list models type molecule", - true); + List modelList = new ArrayList<>(); + String command = "list models type " + + (isChimeraX ? "AtomicStructure" : "molecule"); + List list = sendChimeraCommand(command, true); if (list != null) { for (String modelLine : list) { - ChimeraModel chimeraModel = new ChimeraModel(modelLine); - modelList.add(chimeraModel); + try + { + ChimeraModel chimeraModel = new ChimeraModel(modelLine); + modelList.add(chimeraModel); + } catch (NullPointerException e) + { + // hack for now + } } } return modelList; @@ -494,7 +535,7 @@ public class ChimeraManager */ public List getPresets() { - ArrayList presetList = new ArrayList(); + ArrayList presetList = new ArrayList<>(); List output = sendChimeraCommand("preset list", true); if (output != null) { @@ -550,22 +591,33 @@ public class ChimeraManager // iterate over possible paths for starting Chimera 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"; - continue; - } try { - List args = new ArrayList(); + // ensure symbolic links are resolved + chimeraPath = Paths.get(chimeraPath).toRealPath().toString(); + isChimeraX = chimeraPath.toLowerCase().contains("chimerax"); + 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"; + continue; + } + List args = new ArrayList<>(); args.add(chimeraPath); // shows Chimera output window but suppresses REST responses: // args.add("--debug"); - args.add("--start"); - args.add("RESTServer"); + if (isChimeraX()) + { + args.add("--cmd"); + args.add("remote rest start"); + } + else + { + args.add("--start"); + args.add("RESTServer"); + } ProcessBuilder pb = new ProcessBuilder(args); chimera = pb.start(); error = ""; @@ -573,7 +625,7 @@ public class ChimeraManager break; } catch (Exception e) { - // Chimera could not be started + // Chimera could not be started using this path error += e.getMessage(); } } @@ -613,15 +665,23 @@ public class ChimeraManager { responses.append("\n" + response); // expect: REST server on host 127.0.0.1 port port_number + // ChimeraX is the same except "REST server started on host..." if (response.startsWith("REST server")) { String[] tokens = response.split(" "); - if (tokens.length == 7 && "port".equals(tokens[5])) + for (int i = 0; i < tokens.length - 1; i++) { - port = Integer.parseInt(tokens[6]); - break; + if ("port".equals(tokens[i])) + { + port = Integer.parseInt(tokens[i + 1]); + break; + } } } + if (port > 0) + { + break; // hack for hanging readLine() + } response = lineReader.readLine(); } } catch (Exception e) @@ -699,8 +759,9 @@ public class ChimeraManager public List getAttrList() { - List attributes = new ArrayList(); - final List reply = sendChimeraCommand("list resattr", true); + List attributes = new ArrayList<>(); + String command = (isChimeraX ? "info " : "list") + "resattr"; + final List reply = sendChimeraCommand(command, true); if (reply != null) { for (String inputLine : reply) @@ -718,7 +779,7 @@ public class ChimeraManager public Map getAttrValues(String aCommand, ChimeraModel model) { - Map values = new HashMap(); + Map values = new HashMap<>(); final List reply = sendChimeraCommand("list residue spec " + model.toSpec() + " attribute " + aCommand, true); if (reply != null) @@ -759,6 +820,8 @@ public class ChimeraManager private volatile boolean busy = false; + private boolean isChimeraX; + /** * Send a command to Chimera. * @@ -772,7 +835,7 @@ public class ChimeraManager */ public List sendChimeraCommand(String command, boolean reply) { - // System.out.println("chimeradebug>> " + command); + System.out.println("chimeradebug>> " + command); if (!isChimeraLaunched() || command == null || "".equals(command.trim())) { @@ -818,15 +881,24 @@ public class ChimeraManager protected List sendRestCommand(String command) { String restUrl = "http://127.0.0.1:" + this.chimeraRestPort + "/run"; - List commands = new ArrayList(1); + List commands = new ArrayList<>(1); + String method = isChimeraX() ? "GET" : "POST"; + if ("GET".equals(method)) + { + command = command.replace(" ", "+").replace("#", "%23") + .replace("|", "%7C").replace(";", "%3B"); + } commands.add(new BasicNameValuePair("command", command)); - List reply = new ArrayList(); + List reply = new ArrayList<>(); BufferedReader response = null; try { - response = HttpClientUtils.doHttpUrlPost(restUrl, commands, CONNECTION_TIMEOUT_MS, - REST_REPLY_TIMEOUT_MS); + response = "GET".equals(method) + ? HttpClientUtils.doHttpGet(restUrl, commands, + CONNECTION_TIMEOUT_MS, REST_REPLY_TIMEOUT_MS) + : HttpClientUtils.doHttpUrlPost(restUrl, commands, + CONNECTION_TIMEOUT_MS, REST_REPLY_TIMEOUT_MS); String line = ""; while ((line = response.readLine()) != null) { @@ -898,4 +970,14 @@ public class ChimeraManager { return chimera; } + + public boolean isChimeraX() + { + return isChimeraX; + } + + public void setChimeraX(boolean b) + { + isChimeraX = b; + } }