{
return null;
}
-
- @Override
- protected void sendAsynchronousCommand(String command, String progressMsg)
- {
- // TODO Auto-generated method stub
-
- }
}
{
return null;
}
-
- @Override
- protected void sendAsynchronousCommand(String command, String progressMsg)
- {
- // TODO Auto-generated method stub
-
- }
-
}
package jalview.ext.jmol;
import jalview.api.FeatureRenderer;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.HiddenColumns;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.gui.IProgressIndicator;
import jalview.io.DataSourceType;
import jalview.io.StructureFile;
import jalview.structure.AtomSpec;
-import jalview.structure.StructureCommandsI.SuperposeData;
+import jalview.structure.StructureCommand;
+import jalview.structure.StructureCommandI;
import jalview.structure.StructureSelectionManager;
import jalview.structures.models.AAStructureBindingModel;
-import jalview.util.MessageManager;
import java.awt.Container;
import java.awt.event.ComponentEvent;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
-import java.util.BitSet;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
}
@Override
- public List<String> executeCommand(String command, boolean getReply)
+ public List<String> executeCommand(StructureCommandI command,
+ boolean getReply)
{
if (command == null)
{
return null;
}
+ String cmd = command.getCommand();
jmolHistory(false);
- if (lastCommand == null || !lastCommand.equals(command))
+ if (lastCommand == null || !lastCommand.equals(cmd))
{
- jmolViewer.evalStringQuiet(command + "\n");
+ jmolViewer.evalStringQuiet(cmd + "\n");
}
jmolHistory(true);
- lastCommand = command;
+ lastCommand = cmd;
return null;
}
sb.append(";set hoverLabel \"").append(toks.nextToken()).append(" ")
.append(toks.nextToken());
sb.append("|").append(label).append("\"");
- executeCommand(sb.toString(), false);
+ executeCommand(new StructureCommand(sb.toString()), false);
}
}
}
if (matches)
{
- // add an entry for every chain in the model
- for (int i = 0; i < pdb.getChains().size(); i++)
- {
- String chid = pdb.getId() + ":"
- + pdb.getChains().elementAt(i).id;
- addChainFile(chid, fileName);
- getChainNames().add(chid);
- }
+ stashFoundChains(pdb, fileName);
notifyLoaded = true;
}
}
}
@Override
- protected int getModelNoForFile(String pdbFile)
+ protected String getModelIdForFile(String pdbFile)
{
if (modelFileNames == null)
{
- return -1;
+ return "";
}
for (int i = 0; i < modelFileNames.length; i++)
{
if (modelFileNames[i].equalsIgnoreCase(pdbFile))
{
- return i;
+ return String.valueOf(i);
}
}
- return -1;
+ return "";
}
@Override
{
return ViewerType.JMOL;
}
+
+ @Override
+ protected String getModelId(int pdbfnum, String file)
+ {
+ return String.valueOf(pdbfnum + 1);
+ }
}
import jalview.datamodel.SequenceI;
import jalview.renderer.seqfeatures.FeatureColourFinder;
import jalview.structure.AtomSpecModel;
+import jalview.structure.StructureCommand;
+import jalview.structure.StructureCommandI;
import jalview.structure.StructureCommandsBase;
import jalview.structure.StructureMapping;
import jalview.structure.StructureSelectionManager;
import java.awt.Color;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
*/
public class JmolCommands extends StructureCommandsBase
{
- private static final String CMD_COLOUR_BY_CHARGE = "select *;color white;select ASP,GLU;color red;"
- + "select LYS,ARG;color blue;select CYS;color yellow";
+ private static final StructureCommand SHOW_BACKBONE = new StructureCommand(
+ "select *; cartoons off; backbone");
- private static final String CMD_COLOUR_BY_CHAIN = "select *;color chain";
+ private static final StructureCommand FOCUS_VIEW = new StructureCommand("zoom 0");
+
+ private static final StructureCommand COLOUR_ALL_WHITE = new StructureCommand(
+ "select *;color white;");
+
+ private static final StructureCommandI COLOUR_BY_CHARGE = new StructureCommand(
+ "select *;color white;select ASP,GLU;color red;"
+ + "select LYS,ARG;color blue;select CYS;color yellow");
+
+ private static final StructureCommandI COLOUR_BY_CHAIN = new StructureCommand(
+ "select *;color chain");
private static final String PIPE = "|";
}
@Override
- public String colourByChain()
+ public StructureCommandI colourByChain()
{
- return CMD_COLOUR_BY_CHAIN;
+ return COLOUR_BY_CHAIN;
}
@Override
- public String colourByCharge()
+ public List<StructureCommandI> colourByCharge()
{
- return CMD_COLOUR_BY_CHARGE;
+ return Arrays.asList(COLOUR_BY_CHARGE);
}
@Override
- public String colourByResidues(Map<String, Color> colours)
+ public List<StructureCommandI> colourByResidues(Map<String, Color> colours)
{
- StringBuilder cmd = new StringBuilder(128);
- cmd.append("select *;color white;");
- cmd.append(super.colourByResidues(colours));
-
- return cmd.toString();
+ List<StructureCommandI> cmds = super.colourByResidues(colours);
+ cmds.add(0, COLOUR_ALL_WHITE);
+ return cmds;
}
@Override
- public String setBackgroundColour(Color col)
+ public StructureCommandI setBackgroundColour(Color col)
{
- return "background " + getColourString(col);
+ return new StructureCommand("background " + getColourString(col));
}
@Override
- public String focusView()
+ public StructureCommandI focusView()
{
- return "zoom 0";
+ return FOCUS_VIEW;
}
@Override
- public String showChains(List<String> toShow)
+ public List<StructureCommandI> showChains(List<String> toShow)
{
StringBuilder atomSpec = new StringBuilder(128);
boolean first = true;
String spec = atomSpec.toString();
String command = "select *;restrict " + spec + ";cartoon;center "
+ spec;
- return command;
+ return Arrays.asList(new StructureCommand(command));
}
/**
* @see https://chemapps.stolaf.edu/jmol/docs/#compare
*/
@Override
- public String superposeStructures(AtomSpecModel refAtoms,
+ public List<StructureCommandI> superposeStructures(AtomSpecModel refAtoms,
AtomSpecModel atomSpec)
{
StringBuilder sb = new StringBuilder(64);
- int refModel = refAtoms.getModels().iterator().next();
- int model2 = atomSpec.getModels().iterator().next();
- sb.append(String.format("compare {%d.1} {%d.1}", model2, refModel));
+ String refModel = refAtoms.getModels().iterator().next();
+ String model2 = atomSpec.getModels().iterator().next();
+ sb.append(String.format("compare {%s.1} {%s.1}", model2, refModel));
sb.append(" SUBSET {(*.CA | *.P) and conformation=1} ATOMS {");
/*
sb.append(getAtomSpec(refAtoms, false)).append(getCommandSeparator())
.append("cartoons");
- return sb.toString();
+ return Arrays.asList(new StructureCommand(sb.toString()));
}
@Override
- public String openCommandFile(String path)
+ public StructureCommandI openCommandFile(String path)
{
/*
* https://chemapps.stolaf.edu/jmol/docs/#script
* not currently used in Jalview
*/
- return "script " + path;
+ return new StructureCommand("script " + path);
}
@Override
- public String saveSession(String filepath)
+ public StructureCommandI saveSession(String filepath)
{
/*
* https://chemapps.stolaf.edu/jmol/docs/#write
* not currently used in Jalview
*/
- return "write \"" + filepath + "\"";
+ return new StructureCommand("write \"" + filepath + "\"");
}
@Override
- protected String getColourCommand(String atomSpec, Color colour)
+ protected StructureCommandI getColourCommand(String atomSpec, Color colour)
{
StringBuilder sb = new StringBuilder(atomSpec.length()+20);
sb.append("select ").append(atomSpec).append(getCommandSeparator())
.append("color").append(getColourString(colour));
- return sb.toString();
+ return new StructureCommand(sb.toString());
}
@Override
StringBuilder sb = new StringBuilder(128);
boolean first = true;
- for (int modelNo : model.getModels())
+ for (String modelNo : model.getModels())
{
for (String chain : model.getChains(modelNo))
{
}
@Override
- public String showBackbone()
+ public List<StructureCommandI> showBackbone()
+ {
+ return Arrays.asList(SHOW_BACKBONE);
+ }
+
+ @Override
+ public StructureCommandI loadFile(String file)
{
- return "select *; cartoons off; backbone";
+ return null;
}
}
--- /dev/null
+package jalview.ext.pymol;
+
+import jalview.structure.AtomSpecModel;
+import jalview.structure.StructureCommand;
+import jalview.structure.StructureCommandI;
+import jalview.structure.StructureCommandsBase;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A class that generates commands to send to PyMol
+ *
+ * @see https://pymolwiki.org/index.php/Category:Commands
+ */
+public class PymolCommands extends StructureCommandsBase
+{
+ private static final StructureCommandI COLOUR_BY_CHAIN = new StructureCommand(
+ "util.cbc");
+
+ /*
+ * because the xml-rpc interface can only accept one command at a time, we can't
+ * concatenate commands and must instead form and send them individually
+ */
+ private static final List<StructureCommandI> COLOR_BY_CHARGE = new ArrayList<>();
+
+ private static final List<StructureCommandI> SHOW_BACKBONE = new ArrayList<>();
+
+ static {
+ COLOR_BY_CHARGE.add(new StructureCommand("color", "white", "*"));
+ COLOR_BY_CHARGE
+ .add(new StructureCommand("color", "red", "resn ASP resn GLU"));
+ COLOR_BY_CHARGE.add(
+ new StructureCommand("color", "blue", "resn LYS resn ARG"));
+ COLOR_BY_CHARGE.add(new StructureCommand("color"));
+ SHOW_BACKBONE.add(new StructureCommand("hide", "everything"));
+ SHOW_BACKBONE.add(new StructureCommand("show", "ribbon"));
+ }
+
+ @Override
+ public StructureCommandI colourByChain()
+ {
+ // https://pymolwiki.org/index.php/CBC
+ // TODO this doesn't execute as an xml-rpc command
+ return COLOUR_BY_CHAIN;
+ }
+
+ @Override
+ public List<StructureCommandI> colourByCharge()
+ {
+ return COLOR_BY_CHARGE;
+ }
+
+ @Override
+ public StructureCommandI setBackgroundColour(Color col)
+ {
+ // https://pymolwiki.org/index.php/Bg_Color
+ return new StructureCommand("bg_color", getColourString(col));
+ }
+
+ /**
+ * Returns a colour formatted suitable for use in viewer command syntax. For
+ * example, red is {@code "0xff0000"}.
+ *
+ * @param c
+ * @return
+ */
+ protected String getColourString(Color c)
+ {
+ return String.format("0x%02x%02x%02x", c.getRed(), c.getGreen(),
+ c.getBlue());
+ }
+
+ @Override
+ public StructureCommandI focusView()
+ {
+ // TODO what?
+ return null;
+ }
+
+ @Override
+ public List<StructureCommandI> showChains(List<String> toShow)
+ {
+ // https://pymolwiki.org/index.php/Show
+ List<StructureCommandI> commands = new ArrayList<>();
+ commands.add(new StructureCommand("hide", "everything"));
+ commands.add(new StructureCommand("show", "lines"));
+ StringBuilder chains = new StringBuilder();
+ for (String chain : toShow)
+ {
+ chains.append(" chain ").append(chain);
+ }
+ commands.add(new StructureCommand("show", "cartoon", chains.toString()));
+ return commands;
+ }
+
+ @Override
+ public List<StructureCommandI> superposeStructures(AtomSpecModel refAtoms,
+ AtomSpecModel atomSpec)
+ {
+ // https://pymolwiki.org/index.php/Super
+ List<StructureCommandI> commands = new ArrayList<>();
+ String refAtomsAlphaOnly = getAtomSpec(refAtoms, true);
+ String atomSpec2AlphaOnly = getAtomSpec(atomSpec, true);
+ commands.add(new StructureCommand("super", refAtomsAlphaOnly,
+ atomSpec2AlphaOnly));
+
+ /*
+ * and show superposed residues as cartoon
+ */
+ String refAtomsAll = getAtomSpec(refAtoms, false);
+ String atomSpec2All = getAtomSpec(atomSpec, false);
+ commands.add(new StructureCommand("show", "cartoon",
+ refAtomsAll + " " + atomSpec2All));
+
+ return commands;
+ }
+
+ @Override
+ public StructureCommandI openCommandFile(String path)
+ {
+ // where is this documented by PyMol?
+ // todo : xml-rpc answers 'method "@" is not supported'
+ return new StructureCommand("@" + path); // should be .pml
+ }
+
+ @Override
+ public StructureCommandI saveSession(String filepath)
+ {
+ // https://pymolwiki.org/index.php/Save#EXAMPLES
+ return new StructureCommand("save", filepath); // should be .pse
+ }
+
+ /**
+ * Returns a selection string in PyMOL 'selection macro' format:
+ *
+ * <pre>
+ * modelId// chain/residues/
+ * </pre>
+ *
+ * If more than one chain, makes a selection expression for each, and they are
+ * separated by spaces.
+ *
+ * @see https://pymolwiki.org/index.php/Selection_Macros
+ */
+ @Override
+ public String getAtomSpec(AtomSpecModel model, boolean alphaOnly)
+ {
+ StringBuilder sb = new StringBuilder(64);
+ boolean first = true;
+ for (String modelId : model.getModels())
+ {
+ for (String chain : model.getChains(modelId))
+ {
+ if (!first)
+ {
+ sb.append(" ");
+ }
+ first = false;
+ List<int[]> rangeList = model.getRanges(modelId, chain);
+ chain = chain.trim();
+ sb.append(modelId).append("//").append(chain).append("/");
+ boolean firstRange = true;
+ for (int[] range : rangeList)
+ {
+ if (!firstRange)
+ {
+ sb.append("+");
+ }
+ firstRange = false;
+ sb.append(String.valueOf(range[0]));
+ if (range[0] != range[1])
+ {
+ sb.append("-").append(String.valueOf(range[1]));
+ }
+ }
+ sb.append("/");
+ if (alphaOnly)
+ {
+ sb.append("CA");
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public List<StructureCommandI> showBackbone()
+ {
+ return SHOW_BACKBONE;
+ }
+
+ @Override
+ protected StructureCommandI getColourCommand(String atomSpec, Color colour)
+ {
+ // https://pymolwiki.org/index.php/Color
+ return new StructureCommand("color", getColourString(colour), atomSpec);
+ }
+
+ @Override
+ protected String getResidueSpec(String residue)
+ {
+ // https://pymolwiki.org/index.php/Selection_Algebra
+ return "resn " + residue;
+ }
+
+ @Override
+ public StructureCommandI loadFile(String file)
+ {
+ return new StructureCommand("load", file);
+ }
+
+}
--- /dev/null
+package jalview.ext.pymol;
+
+import jalview.bin.Cache;
+import jalview.gui.Preferences;
+import jalview.structure.StructureCommand;
+import jalview.structure.StructureCommandI;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PymolManager
+{
+ private static final int RPC_REPLY_TIMEOUT_MS = 15000;
+
+ private static final int CONNECTION_TIMEOUT_MS = 100;
+
+ private static final String POST1 = "<methodCall><methodName>";
+
+ private static final String POST2 = "</methodName><params>";
+
+ private static final String POST3 = "</params></methodCall>";
+
+ private Process pymolProcess;
+
+ private int pymolXmlRpcPort;
+
+ /**
+ * Returns a list of paths to try for the PyMOL executable. Any user
+ * preference is placed first, otherwise 'standard' paths depending on the
+ * operating system.
+ *
+ * @return
+ */
+ public static List<String> getPymolPaths()
+ {
+ List<String> pathList = new ArrayList<>();
+
+ String userPath = Cache
+ .getDefault(Preferences.PYMOL_PATH, null);
+ if (userPath != null)
+ {
+ pathList.add(0, userPath);
+ }
+
+ /*
+ * add default installation paths
+ */
+ String pymol = "PyMOL";
+ String os = System.getProperty("os.name");
+ if (os.startsWith("Linux"))
+ {
+ pathList.add("/usr/local/pymol/bin/" + pymol);
+ pathList.add("/usr/local/bin/" + pymol);
+ pathList.add("/usr/bin/" + pymol);
+ pathList.add(System.getProperty("user.home") + "/opt/bin/" + pymol);
+ }
+ else if (os.startsWith("Windows"))
+ {
+ // todo Windows installation path(s)
+ }
+ else if (os.startsWith("Mac"))
+ {
+ pathList.add("/Applications/PyMOL.app/Contents/MacOS/" + pymol);
+ }
+ return pathList;
+ }
+
+ public boolean isPymolLaunched()
+ {
+ // TODO pull up generic methods for external viewer processes
+ boolean launched = false;
+ if (pymolProcess != null)
+ {
+ try
+ {
+ pymolProcess.exitValue();
+ // if we get here, process has ended
+ } catch (IllegalThreadStateException e)
+ {
+ // ok - not yet terminated
+ launched = true;
+ }
+ }
+ return launched;
+ }
+
+ public void exitPymol()
+ {
+ if (isPymolLaunched() && pymolProcess != null)
+ {
+ sendCommand(new StructureCommand("quit"), false);
+ }
+ pymolProcess = null;
+ // currentModelsMap.clear();
+ this.pymolXmlRpcPort = 0;
+ }
+
+ /**
+ * Sends the command to Pymol; if requested, tries to get and return any
+ * replies, else returns null
+ *
+ * @param command
+ * @param getReply
+ * @return
+ */
+ public List<String> sendCommand(StructureCommandI command,
+ boolean getReply)
+ {
+ String postBody = getPostRequest(command);
+ // System.out.println(postBody);// debug
+ String rpcUrl = "http://127.0.0.1:" + this.pymolXmlRpcPort;
+ PrintWriter out = null;
+ BufferedReader in = null;
+ List<String> result = new ArrayList<>();
+ try
+ {
+ URL realUrl = new URL(rpcUrl);
+ URLConnection conn = realUrl.openConnection();
+ conn.setRequestProperty("accept", "*/*");
+ conn.setRequestProperty("content-type", "text/xml");
+ conn.setDoOutput(true);
+ conn.setDoInput(true);
+ out = new PrintWriter(conn.getOutputStream());
+ out.print(postBody);
+ out.flush();
+ in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+ String line;
+ while ((line = in.readLine()) != null)
+ {
+ result.add(line);
+ }
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ } finally
+ {
+ try
+ {
+ if (out != null)
+ {
+ out.close();
+ }
+ if (in != null)
+ {
+ in.close();
+ }
+ } catch (IOException ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Builds the body of the XML-RPC format POST request to execute the command
+ *
+ * @param command
+ * @return
+ */
+ static String getPostRequest(StructureCommandI command)
+ {
+ StringBuilder sb = new StringBuilder(64);
+ sb.append(POST1).append(command.getCommand()).append(POST2);
+ if (command.hasParameters())
+ {
+ for (String p : command.getParameters())
+ {
+ /*
+ * for now assuming all are string - <string> element is optional
+ * refactor in future if other data types needed
+ * https://www.tutorialspoint.com/xml-rpc/xml_rpc_data_model.htm
+ */
+ sb.append("<parameter><value>").append(p)
+ .append("</value></parameter>");
+ }
+ }
+ sb.append(POST3);
+ return sb.toString();
+ }
+
+ public boolean launchPymol()
+ {
+ // todo pull up much of this
+ // Do nothing if already launched
+ if (isPymolLaunched())
+ {
+ return true;
+ }
+
+ String error = "Error message: ";
+ for (String pymolPath : getPymolPaths())
+ {
+ try
+ {
+ // ensure symbolic links are resolved
+ pymolPath = Paths.get(pymolPath).toRealPath().toString();
+ File path = new File(pymolPath);
+ // uncomment the next line to simulate Pymol not installed
+ // path = new File(pymolPath + "x");
+ if (!path.canExecute())
+ {
+ error += "File '" + path + "' does not exist.\n";
+ continue;
+ }
+ List<String> args = new ArrayList<>();
+ args.add(pymolPath);
+ args.add("-R"); // https://pymolwiki.org/index.php/RPC
+ ProcessBuilder pb = new ProcessBuilder(args);
+ pymolProcess = pb.start();
+ error = "";
+ break;
+ } catch (Exception e)
+ {
+ // pPymol could not be started using this path
+ error += e.getMessage();
+ }
+ }
+ if (error.length() == 0)
+ {
+ this.pymolXmlRpcPort = getPortNumber();
+ System.out.println(
+ "PyMOL XMLRPC started on port " + pymolXmlRpcPort);
+ return (pymolXmlRpcPort > 0);
+ }
+
+ // logger.warn(error);
+ return false;
+ }
+
+ private int getPortNumber()
+ {
+ // TODO pull up most of this!
+ int port = 0;
+ InputStream readChan = pymolProcess.getInputStream();
+ BufferedReader lineReader = new BufferedReader(
+ new InputStreamReader(readChan));
+ StringBuilder responses = new StringBuilder();
+ try
+ {
+ String response = lineReader.readLine();
+ while (response != null)
+ {
+ responses.append("\n" + response);
+ // expect: xml-rpc server running on host localhost, port 9123
+ if (response.contains("xml-rpc"))
+ {
+ String[] tokens = response.split(" ");
+ for (int i = 0; i < tokens.length - 1; i++)
+ {
+ 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)
+ {
+ System.err.println(
+ "Failed to get REST port number from " + responses + ": "
+ + e.getMessage());
+ // logger.error("Failed to get REST port number from " + responses + ": "
+ // + e.getMessage());
+ } finally
+ {
+ try
+ {
+ lineReader.close();
+ } catch (IOException e2)
+ {
+ }
+ }
+ if (port == 0)
+ {
+ System.err.println("Failed to start PyMOL with XMLRPC, response was: "
+ + responses);
+ }
+ System.err.println("PyMOL started with XMLRPC on port " + port);
+ return port;
+ }
+
+}
import jalview.datamodel.SequenceI;
import jalview.gui.Desktop;
import jalview.structure.AtomSpecModel;
+import jalview.structure.StructureCommand;
+import jalview.structure.StructureCommandI;
import jalview.structure.StructureCommandsBase;
import jalview.structure.StructureMapping;
import jalview.structure.StructureSelectionManager;
import jalview.util.ColorUtils;
-import jalview.util.IntRangeComparator;
import java.awt.Color;
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Arrays;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
*/
public class ChimeraCommands extends StructureCommandsBase
{
+ private static final StructureCommand SHOW_BACKBONE = new StructureCommand("~display all;chain @CA|P");
+
public static final String NAMESPACE_PREFIX = "jv_";
- private static final String CMD_COLOUR_BY_CHARGE = "color white;color red ::ASP;color red ::GLU;color blue ::LYS;color blue ::ARG;color yellow ::CYS";
+ private static final StructureCommandI COLOUR_BY_CHARGE = new StructureCommand(
+ "color white;color red ::ASP;color red ::GLU;color blue ::LYS;color blue ::ARG;color yellow ::CYS");
- private static final String CMD_COLOUR_BY_CHAIN = "rainbow chain";
+ private static final StructureCommandI COLOUR_BY_CHAIN = new StructureCommand(
+ "rainbow chain");
// Chimera clause to exclude alternate locations in atom selection
private static final String NO_ALTLOCS = "&~@.B-Z&~@.2-9";
@Override
- public String getColourCommand(String atomSpec, Color colour)
+ public StructureCommandI getColourCommand(String atomSpec, Color colour)
{
// https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/color.html
String colourCode = getColourString(colour);
- return "color " + colourCode + " " + atomSpec;
+ return new StructureCommand("color " + colourCode + " " + atomSpec);
}
/**
* @return
*/
@Override
- public String[] setAttributesForFeatures(
+ public List<StructureCommandI> setAttributesForFeatures(
StructureSelectionManager ssm, String[] files, SequenceI[][] seqs,
AlignmentViewPanel viewPanel)
{
for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
final int modelNumber = pdbfnum + getModelStartNo();
+ String modelId = String.valueOf(modelNumber);
StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
if (mapping == null || mapping.length < 1)
if (!visibleFeatures.isEmpty())
{
scanSequenceFeatures(visibleFeatures, structureMapping, seq,
- theMap, modelNumber);
+ theMap, modelId);
}
if (showLinkedFeatures)
{
scanComplementFeatures(complementRenderer, structureMapping,
- seq, theMap, modelNumber);
+ seq, theMap, modelId);
}
}
}
protected static void scanComplementFeatures(
FeatureRenderer complementRenderer,
StructureMapping structureMapping, SequenceI seq,
- Map<String, Map<Object, AtomSpecModel>> theMap, int modelNumber)
+ Map<String, Map<Object, AtomSpecModel>> theMap,
+ String modelNumber)
{
/*
* for each sequence residue mapped to a structure position...
}
/**
- * Inspect features on the sequence; for each feature that is visible, determine
- * its mapped ranges in the structure (if any) according to the given mapping,
- * and add them to the map.
+ * Inspect features on the sequence; for each feature that is visible,
+ * determine its mapped ranges in the structure (if any) according to the
+ * given mapping, and add them to the map.
*
* @param visibleFeatures
* @param mapping
* @param seq
* @param theMap
- * @param modelNumber
+ * @param modelId
*/
protected static void scanSequenceFeatures(List<String> visibleFeatures,
StructureMapping mapping, SequenceI seq,
- Map<String, Map<Object, AtomSpecModel>> theMap, int modelNumber)
+ Map<String, Map<Object, AtomSpecModel>> theMap, String modelId)
{
List<SequenceFeature> sfs = seq.getFeatures().getPositionalFeatures(
visibleFeatures.toArray(new String[visibleFeatures.size()]));
}
for (int[] range : mappedRanges)
{
- addAtomSpecRange(featureValues, value, modelNumber, range[0],
+ addAtomSpecRange(featureValues, value, modelId, range[0],
range[1], mapping.getChain());
}
}
* @param featureMap
* @return
*/
- protected String[] setAttributes(
+ protected List<StructureCommandI> setAttributes(
Map<String, Map<Object, AtomSpecModel>> featureMap)
{
- List<String> commands = new ArrayList<>();
+ List<StructureCommandI> commands = new ArrayList<>();
for (String featureType : featureMap.keySet())
{
String attributeName = makeAttributeName(featureType);
AtomSpecModel atomSpecModel = values.get(value);
String featureValue = value.toString();
featureValue = featureValue.replaceAll("\\'", "'");
- String cmd = setAttribute(attributeName, featureValue,
+ StructureCommandI cmd = setAttribute(attributeName, featureValue,
atomSpecModel);
commands.add(cmd);
}
}
- return commands.toArray(new String[commands.size()]);
+ return commands;
}
/**
* @param atomSpecModel
* @return
*/
- protected String setAttribute(String attributeName,
+ protected StructureCommandI setAttribute(String attributeName,
String attributeValue,
AtomSpecModel atomSpecModel)
{
sb.append("setattr res ").append(attributeName).append(" '")
.append(attributeValue).append("' ");
sb.append(getAtomSpec(atomSpecModel, false));
- return sb.toString();
+ return new StructureCommand(sb.toString());
}
/**
}
@Override
- public String colourByChain()
+ public StructureCommandI colourByChain()
{
- return CMD_COLOUR_BY_CHAIN;
+ return COLOUR_BY_CHAIN;
}
@Override
- public String colourByCharge()
+ public List<StructureCommandI> colourByCharge()
{
- return CMD_COLOUR_BY_CHARGE;
+ return Arrays.asList(COLOUR_BY_CHARGE);
}
@Override
}
@Override
- public String setBackgroundColour(Color col)
+ public StructureCommandI setBackgroundColour(Color col)
{
// https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/set.html#bgcolor
- return "set bgColor " + ColorUtils.toTkCode(col);
+ return new StructureCommand("set bgColor " + ColorUtils.toTkCode(col));
}
@Override
- public String focusView()
+ public StructureCommandI focusView()
{
// https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/focus.html
- return "focus";
+ return new StructureCommand("focus");
}
@Override
- public String showChains(List<String> toShow)
+ public List<StructureCommandI> showChains(List<String> toShow)
{
/*
* Construct a chimera command like
*/
final String command = "~display #*; ~ribbon #*; ribbon :"
+ cmd.toString();
- return command;
+ return Arrays.asList(new StructureCommand(command));
}
@Override
- public String superposeStructures(AtomSpecModel spec, AtomSpecModel ref)
+ public List<StructureCommandI> superposeStructures(AtomSpecModel spec,
+ AtomSpecModel ref)
{
/*
* Form Chimera match command to match spec to ref
cmd.append("match ").append(atomSpec).append(" ").append(refSpec);
/*
- * show superposed residues as ribbon, others as chain
+ * show superposed residues as ribbon
*/
- // fixme this should precede the loop over all alignments/structures
- cmd.append(";~display all; chain @CA|P");
cmd.append("; ribbon ");
cmd.append(atomSpec).append("|").append(refSpec).append("; focus");
- return cmd.toString();
+ return Arrays.asList(new StructureCommand(cmd.toString()));
}
@Override
- public String openCommandFile(String path)
+ public StructureCommandI openCommandFile(String path)
{
// https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/filetypes.html
- return "open cmd:" + path;
+ return new StructureCommand("open cmd:" + path);
}
@Override
- public String saveSession(String filepath)
+ public StructureCommandI saveSession(String filepath)
{
// https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/save.html
- return "save " + filepath;
+ return new StructureCommand("save " + filepath);
}
/**
{
StringBuilder sb = new StringBuilder(128);
boolean firstModel = true;
- for (Integer model : atomSpec.getModels())
+ for (String model : atomSpec.getModels())
{
if (!firstModel)
{
* @param atomSpec
* @param alphaOnly
*/
- protected void appendModel(StringBuilder sb, Integer model,
+ protected void appendModel(StringBuilder sb, String model,
AtomSpecModel atomSpec, boolean alphaOnly)
{
sb.append("#").append(model).append(":");
chain = " ".equals(chain) ? chain : chain.trim();
List<int[]> rangeList = atomSpec.getRanges(model, chain);
-
- /*
- * sort ranges into ascending start position order
- */
- Collections.sort(rangeList, IntRangeComparator.ASCENDING);
-
- int start = rangeList.isEmpty() ? 0 : rangeList.get(0)[0];
- int end = rangeList.isEmpty() ? 0 : rangeList.get(0)[1];
-
- Iterator<int[]> iterator = rangeList.iterator();
- while (iterator.hasNext())
+ for (int[] range : rangeList)
{
- int[] range = iterator.next();
- if (range[0] <= end + 1)
- {
- /*
- * range overlaps or is contiguous with the last one
- * - so just extend the end position, and carry on
- * (unless this is the last in the list)
- */
- end = Math.max(end, range[1]);
- }
- else
- {
- /*
- * we have a break so append the last range
- */
- appendRange(sb, start, end, chain, firstPositionForModel, false);
- firstPositionForModel = false;
- start = range[0];
- end = range[1];
- }
- }
-
- /*
- * and append the last range
- */
- if (!rangeList.isEmpty())
- {
- appendRange(sb, start, end, chain, firstPositionForModel, false);
+ appendRange(sb, range[0], range[1], chain, firstPositionForModel,
+ false);
firstPositionForModel = false;
}
}
}
@Override
- public String showBackbone()
+ public List<StructureCommandI> showBackbone()
+ {
+ return Arrays.asList(SHOW_BACKBONE);
+ }
+
+ @Override
+ public StructureCommandI loadFile(String file)
{
- return "~display all;chain @CA|P";
+ return new StructureCommand("open " + file);
}
}
package jalview.ext.rbvi.chimera;
import jalview.structure.AtomSpecModel;
+import jalview.structure.StructureCommand;
+import jalview.structure.StructureCommandI;
import jalview.util.ColorUtils;
-import jalview.util.IntRangeComparator;
import java.awt.Color;
-import java.util.Collections;
-import java.util.Iterator;
+import java.util.Arrays;
import java.util.List;
/**
*/
public class ChimeraXCommands extends ChimeraCommands
{
- private static final String CMD_COLOUR_BY_CHARGE = "color white;color :ASP,GLU red;color :LYS,ARG blue;color :CYS yellow";
+ private static final StructureCommand SHOW_BACKBONE = new StructureCommand(
+ "~display all;show @CA|P pbonds");
+
+ private static final StructureCommand FOCUS_VIEW = new StructureCommand(
+ "view");
+
+ private static final StructureCommandI COLOUR_BY_CHARGE = new StructureCommand(
+ "color white;color :ASP,GLU red;color :LYS,ARG blue;color :CYS yellow");
@Override
- public String colourByCharge()
+ public List<StructureCommandI> colourByCharge()
{
- return CMD_COLOUR_BY_CHARGE;
+ return Arrays.asList(COLOUR_BY_CHARGE);
}
@Override
}
@Override
- public String setBackgroundColour(Color col)
+ public StructureCommandI setBackgroundColour(Color col)
{
// https://www.cgl.ucsf.edu/chimerax/docs/user/commands/set.html
- return "set bgColor " + ColorUtils.toTkCode(col);
+ return new StructureCommand("set bgColor " + ColorUtils.toTkCode(col));
}
@Override
- public String getColourCommand(String atomSpec, Color colour)
+ public StructureCommandI getColourCommand(String atomSpec, Color colour)
{
// https://www.cgl.ucsf.edu/chimerax/docs/user/commands/color.html
String colourCode = getColourString(colour);
- return "color " + atomSpec + " " + colourCode;
+ return new StructureCommand("color " + atomSpec + " " + colourCode);
}
@Override
- public String focusView()
+ public StructureCommandI focusView()
{
// https://www.cgl.ucsf.edu/chimerax/docs/user/commands/view.html
- return "view";
+ return FOCUS_VIEW;
}
/**
* @return
*/
@Override
- protected String setAttribute(String attributeName,
+ protected StructureCommandI setAttribute(String attributeName,
String attributeValue, AtomSpecModel atomSpecModel)
{
StringBuilder sb = new StringBuilder(128);
sb.append(" res ").append(attributeName).append(" '")
.append(attributeValue).append("'");
sb.append(" create true");
- return sb.toString();
+ return new StructureCommand(sb.toString());
}
@Override
- public String openCommandFile(String path)
+ public StructureCommandI openCommandFile(String path)
{
// https://www.cgl.ucsf.edu/chimerax/docs/user/commands/open.html
- return "open " + path;
+ return new StructureCommand("open " + path);
}
@Override
- public String saveSession(String filepath)
+ public StructureCommandI saveSession(String filepath)
{
// https://www.cgl.ucsf.edu/chimerax/docs/user/commands/save.html
- return "save session " + filepath;
+ return new StructureCommand("save session " + filepath);
}
/**
{
StringBuilder sb = new StringBuilder(128);
boolean firstModel = true;
- for (Integer model : atomSpec.getModels())
+ for (String model : atomSpec.getModels())
{
if (!firstModel)
{
* @param model
* @param atomSpec
*/
- protected void appendModel(StringBuilder sb, Integer model,
+ protected void appendModel(StringBuilder sb, String model,
AtomSpecModel atomSpec)
{
sb.append("#").append(model);
boolean firstPositionForChain = true;
sb.append("/").append(chain.trim()).append(":");
List<int[]> rangeList = atomSpec.getRanges(model, chain);
-
- /*
- * sort ranges into ascending start position order
- */
- Collections.sort(rangeList, IntRangeComparator.ASCENDING);
-
- int start = rangeList.isEmpty() ? 0 : rangeList.get(0)[0];
- int end = rangeList.isEmpty() ? 0 : rangeList.get(0)[1];
-
- Iterator<int[]> iterator = rangeList.iterator();
- while (iterator.hasNext())
+ boolean first = true;
+ for (int[] range : rangeList)
{
- int[] range = iterator.next();
- if (range[0] <= end + 1)
+ if (!first)
{
- /*
- * range overlaps or is contiguous with the last one
- * - so just extend the end position, and carry on
- * (unless this is the last in the list)
- */
- end = Math.max(end, range[1]);
+ sb.append(",");
}
- else
- {
- /*
- * we have a break so append the last range
- */
- appendRange(sb, start, end, chain, firstPositionForChain, true);
- start = range[0];
- end = range[1];
- firstPositionForChain = false;
- }
- }
-
- /*
- * and append the last range
- */
- if (!rangeList.isEmpty())
- {
- appendRange(sb, start, end, chain, firstPositionForChain, true);
+ first = false;
+ appendRange(sb, range[0], range[1], chain, firstPositionForChain,
+ true);
}
- firstPositionForChain = false;
}
}
@Override
- public String showBackbone()
+ public List<StructureCommandI> showBackbone()
{
- return "~display all;show @CA|P pbonds";
+ return Arrays.asList(SHOW_BACKBONE);
}
@Override
- public String superposeStructures(AtomSpecModel spec, AtomSpecModel ref)
+ public List<StructureCommandI> superposeStructures(AtomSpecModel spec,
+ AtomSpecModel ref)
{
/*
* Form ChimeraX match command to match spec to ref
cmd.append(getAtomSpec(spec, false)).append("|");
cmd.append(getAtomSpec(ref, false)).append("; view");
- return cmd.toString();
+ return Arrays.asList(new StructureCommand(cmd.toString()));
}
}
import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
import jalview.datamodel.AlignmentI;
-import jalview.datamodel.HiddenColumns;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SearchResultMatchI;
import jalview.datamodel.SearchResultsI;
import jalview.httpserver.AbstractRequestHandler;
import jalview.io.DataSourceType;
import jalview.structure.AtomSpec;
-import jalview.structure.StructureCommandsI.SuperposeData;
+import jalview.structure.StructureCommand;
+import jalview.structure.StructureCommandI;
import jalview.structure.StructureSelectionManager;
import jalview.structures.models.AAStructureBindingModel;
-import jalview.util.MessageManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.net.BindException;
import java.util.ArrayList;
-import java.util.BitSet;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
* @param getResponse
*/
@Override
- public List<String> executeCommand(final String command,
+ public List<String> executeCommand(final StructureCommandI command,
boolean getResponse)
{
if (chimeraManager == null || command == null)
}
List<String> reply = null;
// trim command or it may never find a match in the replyLog!!
+ String cmd = command.getCommand().trim();
List<String> lastReply = chimeraManager
- .sendChimeraCommand(command.trim(), getResponse);
+ .sendChimeraCommand(cmd, getResponse);
if (getResponse)
{
reply = lastReply;
if (debug)
{
- log("Response from command ('" + command + "') was:\n" + lastReply);
+ log("Response from command ('" + cmd + "') was:\n" + lastReply);
}
}
return reply;
}
- /**
- * @param command
- */
- protected void executeWhenReady(String command)
- {
- waitForChimera();
- executeCommand(command, false);
- waitForChimera();
- }
-
- private void waitForChimera()
- {
- while (chimeraManager != null && chimeraManager.isBusy())
- {
- try
- {
- Thread.sleep(15);
- } catch (InterruptedException q)
- {
- }
- }
- }
-
@Override
public synchronized String[] getStructureFiles()
{
* Chimera: https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/save.html
* ChimeraX: https://www.cgl.ucsf.edu/chimerax/docs/user/commands/save.html
*/
- String command = getCommandGenerator().saveSession(filepath);
+ String command = getCommandGenerator().saveSession(filepath)
+ .getCommand();
List<String> reply = chimeraManager.sendChimeraCommand(command, true);
if (reply.contains("Session written"))
{
* Chimera: https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/open.html
* ChimeraX: https://www.cgl.ucsf.edu/chimerax/docs/user/commands/open.html
*/
- executeCommand("open " + filepath, true);
+ executeCommand(getCommandGenerator().loadFile(filepath), true);
// todo: test for failure - how?
return true;
}
return 0;
}
- String[] commands = getCommandGenerator()
+ List<StructureCommandI> commands = getCommandGenerator()
.setAttributesForFeatures(getSsm(), files, getSequence(), avp);
- if (commands.length > 10)
+ if (commands.size() > 10)
{
sendCommandsByFile(commands);
}
else
{
- for (String command : commands)
+ for (StructureCommandI command : commands)
{
sendAsynchronousCommand(command, null);
}
}
- return commands.length;
+ return commands.size();
}
/**
*
* @param commands
*/
- protected void sendCommandsByFile(String[] commands)
+ protected void sendCommandsByFile(List<StructureCommandI> commands)
{
try
{
File tmp = File.createTempFile("chim", getCommandFileExtension());
tmp.deleteOnExit();
PrintWriter out = new PrintWriter(new FileOutputStream(tmp));
- for (String command : commands)
+ for (StructureCommandI command : commands)
{
- out.println(command);
+ out.println(command.getCommand());
}
out.flush();
out.close();
String path = tmp.getAbsolutePath();
- String command = getCommandGenerator().openCommandFile(path);
+ StructureCommandI command = getCommandGenerator()
+ .openCommandFile(path);
sendAsynchronousCommand(command, null);
} catch (IOException e)
{
// fails for 'average.bfactor' (which is bad):
String cmd = "list residues attr '" + attName + "'";
- List<String> residues = executeCommand(cmd, true);
+ List<String> residues = executeCommand(new StructureCommand(cmd), true);
boolean featureAdded = createFeaturesForAttributes(attName, residues);
if (featureAdded)
}
@Override
- public int getModelNoForFile(String pdbFile)
+ public String getModelIdForFile(String pdbFile)
{
List<ChimeraModel> foundModels = chimeraMaps.get(pdbFile);
if (foundModels != null && !foundModels.isEmpty())
{
- return foundModels.get(0).getModelNumber();
+ return String.valueOf(foundModels.get(0).getModelNumber());
}
- return -1;
+ return "";
}
/**
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.gui.StructureViewer.ViewerType;
+import jalview.structure.StructureCommand;
import jalview.structures.models.AAStructureBindingModel;
import jalview.util.BrowserLauncher;
import jalview.util.ImageMaker;
{
command = "";
}
- jmb.executeCommand(command, false);
- jmb.executeCommand("set hoverDelay=0.1", false);
+ jmb.executeCommand(new StructureCommand(command), false);
+ jmb.executeCommand(new StructureCommand("set hoverDelay=0.1"), false);
jmb.setFinishedInit(true);
}
cmd.append("loadingJalviewdata=true\nload APPEND ");
cmd.append(filesString);
cmd.append("\nloadingJalviewdata=null");
- final String command = cmd.toString();
+ final StructureCommand command = new StructureCommand(cmd.toString());
lastnotify = jmb.getLoadNotifiesHandled();
try
import jalview.api.AlignmentViewPanel;
import jalview.api.FeatureRenderer;
import jalview.bin.Cache;
-import jalview.datamodel.AlignmentI;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.ext.rbvi.chimera.JalviewChimeraBinding;
import jalview.util.BrowserLauncher;
import jalview.util.MessageManager;
import jalview.util.Platform;
-import jalview.ws.dbsources.Pdb;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
pdb = jmb.getSsm().setMapping(jmb.getSequence()[pos],
jmb.getChains()[pos], pe.getFile(), protocol,
getProgressIndicator());
- stashFoundChains(pdb, pe.getFile());
+ jmb.stashFoundChains(pdb, pe.getFile());
} catch (OutOfMemoryError oomerror)
{
worker = null;
}
- /**
- * Fetch PDB data and save to a local file. Returns the full path to the file,
- * or null if fetch fails. TODO: refactor to common with Jmol ? duplication
- *
- * @param processingEntry
- * @return
- * @throws Exception
- */
-
- private void stashFoundChains(StructureFile pdb, String file)
- {
- for (int i = 0; i < pdb.getChains().size(); i++)
- {
- String chid = new String(
- pdb.getId() + ":" + pdb.getChains().elementAt(i).id);
- jmb.getChainNames().add(chid);
- jmb.addChainFile(chid, file);
- }
- }
-
- private String fetchPdbFile(PDBEntry processingEntry) throws Exception
- {
- String filePath = null;
- Pdb pdbclient = new Pdb();
- AlignmentI pdbseq = null;
- String pdbid = processingEntry.getId();
- long handle = System.currentTimeMillis()
- + Thread.currentThread().hashCode();
-
- /*
- * Write 'fetching PDB' progress on AlignFrame as we are not yet visible
- */
- String msg = MessageManager.formatMessage("status.fetching_pdb",
- new Object[]
- { pdbid });
- getAlignmentPanel().alignFrame.setProgressBar(msg, handle);
- // long hdl = startProgressBar(MessageManager.formatMessage(
- // "status.fetching_pdb", new Object[]
- // { pdbid }));
- try
- {
- pdbseq = pdbclient.getSequenceRecords(pdbid);
- } catch (OutOfMemoryError oomerror)
- {
- new OOMWarning("Retrieving PDB id " + pdbid, oomerror);
- } finally
- {
- msg = pdbid + " " + MessageManager.getString("label.state_completed");
- getAlignmentPanel().alignFrame.setProgressBar(msg, handle);
- // stopProgressBar(msg, hdl);
- }
- /*
- * If PDB data were saved and are not invalid (empty alignment), return the
- * file path.
- */
- if (pdbseq != null && pdbseq.getHeight() > 0)
- {
- // just use the file name from the first sequence's first PDBEntry
- filePath = new File(pdbseq.getSequenceAt(0).getAllPDBEntries()
- .elementAt(0).getFile()).getAbsolutePath();
- processingEntry.setFile(filePath);
- }
- return filePath;
- }
-
@Override
public void eps_actionPerformed()
{
import jalview.ext.rbvi.chimera.ChimeraXCommands;
import jalview.gui.StructureViewer.ViewerType;
import jalview.io.DataSourceType;
+import jalview.structure.StructureCommand;
import jalview.structure.StructureSelectionManager;
import java.util.List;
int modelNumber = chimeraMaps.size() + 1;
String command = "setattr #" + modelNumber + " models name "
+ pe.getId();
- executeCommand(command, false);
+ executeCommand(new StructureCommand(command), false);
modelsToMap.add(new ChimeraModel(pe.getId(), ModelType.PDB_MODEL,
modelNumber, 0));
}
return ViewerType.CHIMERAX;
}
+ @Override
+ protected String getModelId(int pdbfnum, String file)
+ {
+ return String.valueOf(pdbfnum + 1);
+ }
+
}
public static final String CHIMERAX_PATH = "CHIMERAX_PATH";
+ public static final String PYMOL_PATH = "PYMOL_PATH";
+
public static final String SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE";
boolean isChimeraX = viewerType.equals(ViewerType.CHIMERAX.name());
if (viewerType.equals(ViewerType.JMOL.name()))
{
- chimeraPath.setText("");
+ structureViewerPath.setText("");
}
else
{
- chimeraPath.setText(Cache
+ structureViewerPath.setText(Cache
.getDefault(isChimeraX ? CHIMERAX_PATH : CHIMERA_PATH, ""));
}
- chimeraPath.addActionListener(new ActionListener()
+ structureViewerPath.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
Cache.setProperty(structViewer.getSelectedItem()
.equals(ViewerType.CHIMERAX.name())
? CHIMERAX_PATH
- : CHIMERA_PATH, chimeraPath.getText());
+ : CHIMERA_PATH, structureViewerPath.getText());
}
}
});
Boolean.toString(useRnaView.isSelected()));
Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
Boolean.toString(structFromPdb.isSelected()));
+ String viewer = structViewer.getSelectedItem().toString();
+ String viewerPath = structureViewerPath.getText();
Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY,
- structViewer.getSelectedItem().toString());
- boolean isChimeraX = structViewer.getSelectedItem().toString()
- .equals(ViewerType.CHIMERAX.name());
- Cache.setOrRemove(isChimeraX ? CHIMERAX_PATH : CHIMERA_PATH,
- chimeraPath.getText());
+ viewer);
+ if (viewer.equals(ViewerType.CHIMERA.name()))
+ {
+ Cache.setOrRemove(CHIMERA_PATH, viewerPath);
+ }
+ else if (viewer.equals(ViewerType.CHIMERAX.name()))
+ {
+ Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
+ }
+ else if (viewer.equals(ViewerType.PYMOL.name()))
+ {
+ Cache.setOrRemove(PYMOL_PATH, viewerPath);
+ }
Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
Boolean.toString(siftsMapping.isSelected()));
SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
*/
private boolean validateChimeraPath()
{
- if (chimeraPath.getText().trim().length() > 0)
+ if (structureViewerPath.getText().trim().length() > 0)
{
- File f = new File(chimeraPath.getText());
+ File f = new File(structureViewerPath.getText());
if (!f.canExecute())
{
JvOptionPane.showInternalMessageDialog(Desktop.desktop,
}
/**
- * If Chimera or ChimeraX is selected, check it can be found on default or
- * user-specified path, if not show a warning/help dialog.
+ * If Chimera or ChimeraX or Pymol is selected, check it can be found on
+ * default or user-specified path, if not show a warning/help dialog
*/
@Override
protected void structureViewer_actionPerformed(String selectedItem)
{
if (selectedItem.equals(ViewerType.JMOL.name()))
{
- chimeraPath.setEnabled(false);
- chimeraPathLabel.setEnabled(false);
+ structureViewerPath.setEnabled(false);
+ structureViewerPathLabel.setEnabled(false);
return;
}
boolean found = false;
- chimeraPath.setEnabled(true);
- chimeraPathLabel.setEnabled(true);
- chimeraPathLabel.setText(MessageManager
+ structureViewerPath.setEnabled(true);
+ structureViewerPathLabel.setEnabled(true);
+ structureViewerPathLabel.setText(MessageManager
.formatMessage("label.chimera_path", selectedItem));
/*
* Try user-specified and standard paths for Chimera executable
*/
boolean isChimeraX = selectedItem.equals(ViewerType.CHIMERAX.name());
- chimeraPath.setText(Cache
+ structureViewerPath.setText(Cache
.getDefault(isChimeraX ? CHIMERAX_PATH : CHIMERA_PATH, ""));
List<String> paths = StructureManager.getChimeraPaths(isChimeraX);
- paths.add(0, chimeraPath.getText());
+ paths.add(0, structureViewerPath.getText());
for (String path : paths)
{
if (new File(path.trim()).canExecute())
--- /dev/null
+package jalview.gui;
+
+import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.ext.pymol.PymolCommands;
+import jalview.ext.pymol.PymolManager;
+import jalview.gui.StructureViewer.ViewerType;
+import jalview.structure.AtomSpec;
+import jalview.structure.StructureCommandI;
+import jalview.structure.StructureSelectionManager;
+import jalview.structures.models.AAStructureBindingModel;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class PymolBindingModel extends AAStructureBindingModel
+{
+ private PymolManager pymolManager;
+
+ private Thread pymolMonitor;
+
+ /*
+ * full paths to structure files opened in PyMOL
+ */
+ List<String> structureFiles = new ArrayList<>();
+
+ /*
+ * lookup from file path to PyMOL object name
+ */
+ Map<String, String> pymolObjects = new HashMap<>();
+
+ /**
+ * Constructor
+ *
+ * @param viewer
+ * @param ssm
+ * @param pdbentry
+ * @param sequenceIs
+ */
+ public PymolBindingModel(StructureViewerBase viewer,
+ StructureSelectionManager ssm, PDBEntry[] pdbentry,
+ SequenceI[][] sequenceIs)
+ {
+ super(ssm, pdbentry, sequenceIs, null);
+ pymolManager = new PymolManager();
+ setStructureCommands(new PymolCommands());
+ setViewer(viewer);
+ }
+
+ @Override
+ public String[] getStructureFiles()
+ {
+ return structureFiles.toArray(new String[structureFiles.size()]);
+ }
+
+ @Override
+ public void highlightAtoms(List<AtomSpec> atoms)
+ {
+ }
+
+ @Override
+ public SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment)
+ {
+ // pull up?
+ return new SequenceRenderer(alignment.getAlignViewport());
+ }
+
+ @Override
+ protected List<String> executeCommand(StructureCommandI command,
+ boolean getReply)
+ {
+ System.out.println(command.toString()); // debug
+ return pymolManager.sendCommand(command, getReply);
+ }
+
+ @Override
+ protected String getModelIdForFile(String file)
+ {
+ return pymolObjects.containsKey(file) ? pymolObjects.get(file) : "";
+ }
+
+ @Override
+ protected ViewerType getViewerType()
+ {
+ return ViewerType.PYMOL;
+ }
+
+ public boolean isPymolRunning()
+ {
+ return pymolManager.isPymolLaunched();
+ }
+
+ public void closeViewer(boolean closePymol)
+ {
+ getSsm().removeStructureViewerListener(this, this.getStructureFiles());
+ if (closePymol)
+ {
+ pymolManager.exitPymol();
+ }
+ // if (this.pymolListener != null)
+ // {
+ // pymolListener.shutdown();
+ // pymolListener = null;
+ // }
+ pymolManager = null;
+
+ if (pymolMonitor != null)
+ {
+ pymolMonitor.interrupt();
+ }
+ releaseUIResources();
+ }
+
+ public boolean openSession(String pymolSessionFile)
+ {
+ StructureCommandI cmd = getCommandGenerator()
+ .loadFile(pymolSessionFile);
+ executeCommand(cmd, false);
+ return true;
+ }
+
+ public boolean launchPymol()
+ {
+ if (pymolManager.isPymolLaunched())
+ {
+ return true;
+ }
+
+ boolean launched = pymolManager.launchPymol();
+ if (launched)
+ {
+ // start listening for PyMOL selections - how??
+ }
+ else
+ {
+ System.err.println("Failed to launch PyMOL!");
+ }
+ return launched;
+ }
+
+ public void openFile(PDBEntry pe)
+ {
+ // todo : check not already open, remap / rename, etc
+ String file = pe.getFile();
+ StructureCommandI cmd = getCommandGenerator().loadFile(file);
+
+ /*
+ * a second parameter sets the pdbid as the loaded PyMOL object name
+ */
+ String pdbId = pe.getId();
+ cmd.addParameter(pdbId);
+
+ executeCommand(cmd, false);
+
+ pymolObjects.put(file, pdbId);
+ if (!structureFiles.contains(file))
+ {
+ structureFiles.add(file);
+ }
+ if (getSsm() != null)
+ {
+ getSsm().addStructureViewerListener(this);
+ }
+
+ }
+
+ @Override
+ protected String getModelId(int pdbfnum, String file)
+ {
+ return file;
+ }
+
+}
--- /dev/null
+package jalview.gui;
+
+import jalview.api.AlignmentViewPanel;
+import jalview.api.FeatureRenderer;
+import jalview.bin.Cache;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.gui.StructureViewer.ViewerType;
+import jalview.io.DataSourceType;
+import jalview.io.StructureFile;
+import jalview.structures.models.AAStructureBindingModel;
+import jalview.util.MessageManager;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JInternalFrame;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
+
+public class PymolViewer extends StructureViewerBase
+{
+ private static final int myWidth = 500;
+
+ private static final int myHeight = 150;
+
+ private PymolBindingModel binding;
+
+ private String pymolSessionFile;
+
+ public PymolViewer()
+ {
+ super();
+
+ /*
+ * closeViewer will decide whether or not to close this frame
+ * depending on whether user chooses to Cancel or not
+ */
+ setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
+ }
+
+ public PymolViewer(PDBEntry pdb, SequenceI[] seqs, Object object,
+ AlignmentPanel ap)
+ {
+ this();
+ openNewPymol(ap, new PDBEntry[] { pdb },
+ new SequenceI[][]
+ { seqs });
+ }
+
+ public PymolViewer(PDBEntry[] pe, boolean alignAdded, SequenceI[][] seqs,
+ AlignmentPanel ap)
+ {
+ this();
+ setAlignAddedStructures(alignAdded);
+ openNewPymol(ap, pe, seqs);
+ }
+
+ private void openNewPymol(AlignmentPanel ap, PDBEntry[] pe,
+ SequenceI[][] seqs)
+ {
+ createProgressBar();
+ binding = new PymolBindingModel(this, ap.getStructureSelectionManager(),
+ pe, seqs);
+ addAlignmentPanel(ap);
+ useAlignmentPanelForColourbyseq(ap);
+
+ if (pe.length > 1)
+ {
+ useAlignmentPanelForSuperposition(ap);
+ }
+ binding.setColourBySequence(true);
+ setSize(myWidth, myHeight);
+ initMenus();
+
+ addingStructures = false;
+ worker = new Thread(this);
+ worker.start();
+
+ this.addInternalFrameListener(new InternalFrameAdapter()
+ {
+ @Override
+ public void internalFrameClosing(
+ InternalFrameEvent internalFrameEvent)
+ {
+ closeViewer(false);
+ }
+ });
+
+ }
+
+ /**
+ * Create a helper to manage progress bar display
+ */
+ protected void createProgressBar()
+ {
+ if (getProgressIndicator() == null)
+ {
+ setProgressIndicator(new ProgressBar(statusPanel, statusBar));
+ }
+ }
+
+ @Override
+ public void run()
+ {
+ // todo pull up much of this
+
+ StringBuilder errormsgs = new StringBuilder(128);
+ List<PDBEntry> filePDB = new ArrayList<>();
+ List<Integer> filePDBpos = new ArrayList<>();
+ String[] curfiles = binding.getStructureFiles(); // files currently in viewer
+ for (int pi = 0; pi < binding.getPdbCount(); pi++)
+ {
+ String file = null;
+ PDBEntry thePdbEntry = binding.getPdbEntry(pi);
+ if (thePdbEntry.getFile() == null)
+ {
+ /*
+ * Retrieve PDB data, save to file, attach to PDBEntry
+ */
+ file = fetchPdbFile(thePdbEntry);
+ if (file == null)
+ {
+ errormsgs.append("'" + thePdbEntry.getId() + "' ");
+ }
+ }
+ else
+ {
+ /*
+ * got file already
+ */
+ file = new File(thePdbEntry.getFile()).getAbsoluteFile()
+ .getPath();
+ // todo - skip if already loaded in PyMOL
+ }
+ if (file != null)
+ {
+ filePDB.add(thePdbEntry);
+ filePDBpos.add(Integer.valueOf(pi));
+ }
+ }
+
+ if (!filePDB.isEmpty())
+ {
+ /*
+ * at least one structure to add to viewer
+ */
+ binding.setFinishedInit(false);
+ if (!addingStructures)
+ {
+ try
+ {
+ initPymol();
+ } catch (Exception ex)
+ {
+ Cache.log.error("Couldn't open PyMOL viewer!", ex);
+ }
+ }
+ int num = -1;
+ for (PDBEntry pe : filePDB)
+ {
+ num++;
+ if (pe.getFile() != null)
+ {
+ try
+ {
+ int pos = filePDBpos.get(num).intValue();
+ long startTime = startProgressBar(getViewerName() + " "
+ + MessageManager.getString("status.opening_file_for")
+ + " " + pe.getId());
+ binding.openFile(pe);
+ binding.addSequence(pos, binding.getSequence()[pos]);
+ File fl = new File(pe.getFile());
+ DataSourceType protocol = DataSourceType.URL;
+ try
+ {
+ if (fl.exists())
+ {
+ protocol = DataSourceType.FILE;
+ }
+ } catch (Throwable e)
+ {
+ } finally
+ {
+ stopProgressBar("", startTime);
+ }
+
+ StructureFile pdb = binding.getSsm().setMapping(
+ binding.getSequence()[pos], binding.getChains()[pos],
+ pe.getFile(), protocol,
+ getProgressIndicator());
+ binding.stashFoundChains(pdb, pe.getFile());
+ } catch (Exception ex)
+ {
+ Cache.log.error(
+ "Couldn't open " + pe.getFile() + " in Chimera viewer!",
+ ex);
+ } finally
+ {
+ // Cache.log.debug("File locations are " + files);
+ }
+ }
+ }
+
+ binding.refreshGUI();
+ binding.setFinishedInit(true);
+ binding.setLoadingFromArchive(false);
+
+ /*
+ * ensure that any newly discovered features (e.g. RESNUM)
+ * are added to any open feature settings dialog
+ */
+ FeatureRenderer fr = getBinding().getFeatureRenderer(null);
+ if (fr != null)
+ {
+ fr.featuresAdded();
+ }
+
+ // refresh the sequence colours for the new structure(s)
+ for (AlignmentViewPanel ap : _colourwith)
+ {
+ binding.updateColours(ap);
+ }
+ // do superposition if asked to
+ if (alignAddedStructures)
+ {
+ new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ alignStructsWithAllAlignPanels();
+ }
+ }).start();
+ }
+ addingStructures = false;
+ }
+ _started = false;
+ worker = null;
+
+ }
+
+ /**
+ * Launch PyMOL. If we have a session file name, send PyMOL the command to
+ * open its saved session file.
+ */
+ void initPymol()
+ {
+ Desktop.addInternalFrame(this,
+ binding.getViewerTitle(getViewerName(), true),
+ getBounds().width, getBounds().height);
+
+ if (!binding.launchPymol())
+ {
+ JvOptionPane.showMessageDialog(Desktop.desktop,
+ MessageManager.getString("label.pymol_failed"),
+ MessageManager.getString("label.error_loading_file"),
+ JvOptionPane.ERROR_MESSAGE);
+ this.dispose();
+ return;
+ }
+
+ if (this.pymolSessionFile != null)
+ {
+ boolean opened = binding.openSession(pymolSessionFile);
+ if (!opened)
+ {
+ System.err.println("An error occurred opening PyMOL session file "
+ + pymolSessionFile);
+ }
+ }
+ // binding.startPymolListener();
+ }
+
+ @Override
+ public AAStructureBindingModel getBinding()
+ {
+ return binding;
+ }
+
+ @Override
+ public void closeViewer(boolean closePymol)
+ {
+ if (binding != null && binding.isPymolRunning())
+ {
+ if (!closePymol)
+ {
+ // TODO i18n (and pull up)
+ String prompt = MessageManager
+ .formatMessage("label.confirm_close_pymol", new Object[]
+ { binding.getViewerTitle(getViewerName(), false) });
+ prompt = JvSwingUtils.wrapTooltip(true, prompt);
+ int confirm = JvOptionPane.showConfirmDialog(this, prompt,
+ MessageManager.getString("label.close_viewer"),
+ JvOptionPane.YES_NO_CANCEL_OPTION);
+ /*
+ * abort closure if user hits escape or Cancel
+ */
+ if (confirm == JvOptionPane.CANCEL_OPTION
+ || confirm == JvOptionPane.CLOSED_OPTION)
+ {
+ return;
+ }
+ closePymol = confirm == JvOptionPane.YES_OPTION;
+ }
+ binding.closeViewer(closePymol);
+ }
+ setAlignmentPanel(null);
+ _aps.clear();
+ _alignwith.clear();
+ _colourwith.clear();
+ // TODO: check for memory leaks where instance isn't finalised because
+ // binding
+ // holds a reference to the window
+ binding = null;
+ dispose();
+ }
+
+ @Override
+ public String getStateInfo()
+ {
+ return null;
+ }
+
+ @Override
+ public ViewerType getViewerType()
+ {
+ return ViewerType.PYMOL;
+ }
+
+ @Override
+ protected String getViewerName()
+ {
+ return "PyMOL";
+ }
+
+}
public enum ViewerType
{
- JMOL, CHIMERA, CHIMERAX
+ JMOL, CHIMERA, CHIMERAX, PYMOL
};
/**
sview = new ChimeraXViewFrame(pdbsForFile, superposeAdded, theSeqs,
ap);
}
+ else if (viewerType.equals(ViewerType.PYMOL))
+ {
+ sview = new PymolViewer(pdbsForFile, superposeAdded, theSeqs, ap);
+ }
else
{
Cache.log.error(UNKNOWN_VIEWER_TYPE + getViewerType().toString());
{
sview = new ChimeraXViewFrame(pdb, seqsForPdb, null, ap);
}
+ else if (viewerType.equals(ViewerType.PYMOL))
+ {
+ sview = new PymolViewer(pdb, seqsForPdb, null, ap);
+ }
else
{
Cache.log.error(UNKNOWN_VIEWER_TYPE + getViewerType().toString());
import jalview.structure.StructureMapping;
import jalview.structures.models.AAStructureBindingModel;
import jalview.util.MessageManager;
+import jalview.ws.dbsources.Pdb;
import java.awt.Color;
import java.awt.Component;
getBinding().showChains(toshow);
}
+ /**
+ * Tries to fetch a PDB file and save to a temporary local file. Returns the
+ * saved file path if successful, or null if not.
+ *
+ * @param processingEntry
+ * @return
+ */
+ protected String fetchPdbFile(PDBEntry processingEntry)
+ {
+ String filePath = null;
+ Pdb pdbclient = new Pdb();
+ AlignmentI pdbseq = null;
+ String pdbid = processingEntry.getId();
+ long handle = System.currentTimeMillis()
+ + Thread.currentThread().hashCode();
+
+ /*
+ * Write 'fetching PDB' progress on AlignFrame as we are not yet visible
+ */
+ String msg = MessageManager.formatMessage("status.fetching_pdb",
+ new Object[]
+ { pdbid });
+ getAlignmentPanel().alignFrame.setProgressBar(msg, handle);
+ // long hdl = startProgressBar(MessageManager.formatMessage(
+ // "status.fetching_pdb", new Object[]
+ // { pdbid }));
+ try
+ {
+ pdbseq = pdbclient.getSequenceRecords(pdbid);
+ } catch (Exception e)
+ {
+ System.err.println(
+ "Error retrieving PDB id " + pdbid + ": " + e.getMessage());
+ } finally
+ {
+ msg = pdbid + " " + MessageManager.getString("label.state_completed");
+ getAlignmentPanel().alignFrame.setProgressBar(msg, handle);
+ // stopProgressBar(msg, hdl);
+ }
+ /*
+ * If PDB data were saved and are not invalid (empty alignment), return the
+ * file path.
+ */
+ if (pdbseq != null && pdbseq.getHeight() > 0)
+ {
+ // just use the file name from the first sequence's first PDBEntry
+ filePath = new File(pdbseq.getSequenceAt(0).getAllPDBEntries()
+ .elementAt(0).getFile()).getAbsolutePath();
+ processingEntry.setFile(filePath);
+ }
+ return filePath;
+ }
+
}
protected JComboBox<String> structViewer = new JComboBox<>();
- protected JLabel chimeraPathLabel;
+ protected JLabel structureViewerPathLabel;
- protected JTextField chimeraPath = new JTextField();
+ protected JTextField structureViewerPath = new JTextField();
protected ButtonGroup mappingMethod = new ButtonGroup();
structViewer.addItem(ViewerType.JMOL.name());
structViewer.addItem(ViewerType.CHIMERA.name());
structViewer.addItem(ViewerType.CHIMERAX.name());
+ structViewer.addItem(ViewerType.PYMOL.name());
structViewer.addActionListener(new ActionListener()
{
@Override
structureTab.add(structViewer);
ypos += lineSpacing;
- chimeraPathLabel = new JLabel();
- chimeraPathLabel.setFont(LABEL_FONT);// new Font("SansSerif", 0, 11));
- chimeraPathLabel.setHorizontalAlignment(SwingConstants.LEFT);
- chimeraPathLabel.setText(MessageManager
+ structureViewerPathLabel = new JLabel();
+ structureViewerPathLabel.setFont(LABEL_FONT);// new Font("SansSerif", 0, 11));
+ structureViewerPathLabel.setHorizontalAlignment(SwingConstants.LEFT);
+ structureViewerPathLabel.setText(MessageManager
.formatMessage("label.chimera_path", "Chimera(X)"));
- chimeraPathLabel.setBounds(new Rectangle(10, ypos, 170, height));
- chimeraPathLabel.setEnabled(false);
- structureTab.add(chimeraPathLabel);
+ structureViewerPathLabel.setBounds(new Rectangle(10, ypos, 170, height));
+ structureViewerPathLabel.setEnabled(false);
+ structureTab.add(structureViewerPathLabel);
- chimeraPath.setFont(LABEL_FONT);
- chimeraPath.setText("");
- chimeraPath.setEnabled(false);
+ structureViewerPath.setFont(LABEL_FONT);
+ structureViewerPath.setText("");
+ structureViewerPath.setEnabled(false);
final String tooltip = JvSwingUtils.wrapTooltip(true,
MessageManager.getString("label.chimera_path_tip"));
- chimeraPath.setToolTipText(tooltip);
- chimeraPath.setBounds(new Rectangle(190, ypos, 290, height));
- chimeraPath.addMouseListener(new MouseAdapter()
+ structureViewerPath.setToolTipText(tooltip);
+ structureViewerPath.setBounds(new Rectangle(190, ypos, 290, height));
+ structureViewerPath.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
- if (chimeraPath.isEnabled() && e.getClickCount() == 2)
+ if (structureViewerPath.isEnabled() && e.getClickCount() == 2)
{
String chosen = openFileChooser();
if (chosen != null)
{
- chimeraPath.setText(chosen);
+ structureViewerPath.setText(chosen);
}
}
}
});
- structureTab.add(chimeraPath);
+ structureTab.add(structureViewerPath);
ypos += lineSpacing;
nwMapping.setFont(LABEL_FONT);
public class AtomSpecModel
{
/*
- * { modelNo, {chainCode, List<from-to> ranges} }
+ * { modelId, {chainCode, List<from-to> ranges} }
*/
- private Map<Integer, Map<String, BitSet>> atomSpec;
+ private Map<String, Map<String, BitSet>> atomSpec;
/**
* Constructor
* @param endPos
* @param chain
*/
- public void addRange(int model, int startPos, int endPos, String chain)
+ public void addRange(String model, int startPos, int endPos, String chain)
{
/*
* Get/initialize map of data for the colour and model
chainData.set(startPos, endPos + 1);
}
- public Iterable<Integer> getModels()
+ public Iterable<String> getModels()
{
return atomSpec.keySet();
}
- public Iterable<String> getChains(Integer model)
+ public int getModelCount()
+ {
+ return atomSpec.size();
+ }
+
+ public Iterable<String> getChains(String model)
{
return atomSpec.containsKey(model) ? atomSpec.get(model).keySet()
: null;
* @param chain
* @return
*/
- public List<int[]> getRanges(Integer model, String chain)
+ public List<int[]> getRanges(String model, String chain)
{
List<int[]> ranges = new ArrayList<>();
if (atomSpec.containsKey(model))
--- /dev/null
+package jalview.structure;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class StructureCommand implements StructureCommandI
+{
+ private String command;
+
+ private List<String> parameters;
+
+ public StructureCommand(String cmd, String... params)
+ {
+ command = cmd;
+ if (params != null)
+ {
+ for (String p : params)
+ {
+ addParameter(p);
+ }
+ }
+ }
+
+ @Override
+ public void addParameter(String param)
+ {
+ if (parameters == null)
+ {
+ parameters = new ArrayList<>();
+ }
+ parameters.add(param);
+ }
+
+ @Override
+ public String getCommand()
+ {
+ return command;
+ }
+
+ @Override
+ public List<String> getParameters()
+ {
+ return parameters;
+ }
+
+ @Override
+ public boolean hasParameters()
+ {
+ return parameters != null && !parameters.isEmpty();
+ }
+
+ @Override
+ public String toString()
+ {
+ if (!hasParameters())
+ {
+ return command;
+ }
+ StringBuilder sb = new StringBuilder(32);
+ sb.append(command).append("(");
+ boolean first = true;
+ for (String p : parameters)
+ {
+ if (!first)
+ {
+ sb.append(",");
+ }
+ first = false;
+ sb.append(p);
+ }
+ sb.append(")");
+ return sb.toString();
+ }
+
+}
--- /dev/null
+package jalview.structure;
+
+import java.util.List;
+
+public interface StructureCommandI
+{
+ String getCommand();
+
+ List<String> getParameters();
+
+ void addParameter(String param);
+
+ boolean hasParameters();
+}
package jalview.structure;
-import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
-import jalview.api.FeatureRenderer;
-import jalview.api.SequenceRenderer;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.HiddenColumns;
import jalview.datamodel.SequenceI;
-import jalview.renderer.seqfeatures.FeatureColourFinder;
-import jalview.util.Comparison;
import java.awt.Color;
import java.util.ArrayList;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
}
@Override
- public String[] setAttributesForFeatures(StructureSelectionManager ssm,
+ public List<StructureCommandI> setAttributesForFeatures(
+ StructureSelectionManager ssm,
String[] files, SequenceI[][] sequence, AlignmentViewPanel avp)
{
// default does nothing, override where this is implemented
* @param chain
*/
public static final void addAtomSpecRange(Map<Object, AtomSpecModel> map,
- Object value,
- int model, int startPos, int endPos, String chain)
+ Object value, String model, int startPos, int endPos,
+ String chain)
{
/*
* Get/initialize map of data for the colour
* @return
*/
@Override
- public String[] colourBySequence(Map<Object, AtomSpecModel> colourMap)
+ public List<StructureCommandI> colourBySequence(
+ Map<Object, AtomSpecModel> colourMap)
{
/*
- * This version concatenates all commands into a single String (semi-colon
- * delimited). If length limit issues arise, refactor to return one color
- * command per colour.
+ * default implementation creates one command per colour;
+ * override to concatenate colour commands if wanted
*/
- List<String> commands = new ArrayList<>();
- StringBuilder sb = new StringBuilder(256);
- boolean firstColour = true;
+ List<StructureCommandI> commands = new ArrayList<>();
for (Object key : colourMap.keySet())
{
Color colour = (Color) key;
- if (!firstColour)
- {
- sb.append(getCommandSeparator()).append(" ");
- }
- firstColour = false;
final AtomSpecModel colourData = colourMap.get(colour);
- sb.append(getColourCommand(colourData, colour));
+ commands.add(getColourCommand(colourData, colour));
}
- commands.add(sb.toString());
- return commands.toArray(new String[commands.size()]);
+ return commands;
}
/**
* @param colour
* @return
*/
- protected String getColourCommand(AtomSpecModel atomSpecModel, Color colour)
+ protected StructureCommandI getColourCommand(AtomSpecModel atomSpecModel,
+ Color colour)
{
String atomSpec = getAtomSpec(atomSpecModel, false);
return getColourCommand(atomSpec, colour);
* @param colour
* @return
*/
- protected abstract String getColourCommand(String atomSpec, Color colour);
+ protected abstract StructureCommandI getColourCommand(String atomSpec,
+ Color colour);
@Override
- public String colourByResidues(Map<String, Color> colours)
+ public List<StructureCommandI> colourByResidues(
+ Map<String, Color> colours)
{
- StringBuilder cmd = new StringBuilder(12 * colours.size());
-
+ List<StructureCommandI> commands = new ArrayList<>();
for (Entry<String, Color> entry : colours.entrySet())
{
- String residue = entry.getKey();
- String atomSpec = getResidueSpec(residue);
- cmd.append(getColourCommand(atomSpec, entry.getValue()));
- cmd.append(getCommandSeparator());
+ commands.add(colourResidue(entry.getKey(), entry.getValue()));
}
- return cmd.toString();
+ return commands;
+ }
+
+ private StructureCommandI colourResidue(String resName, Color col)
+ {
+ String atomSpec = getResidueSpec(resName);
+ return getColourCommand(atomSpec, col);
}
/**
+++ /dev/null
-package jalview.structure;
-
-import jalview.ext.jmol.JmolCommands;
-import jalview.ext.rbvi.chimera.ChimeraCommands;
-import jalview.ext.rbvi.chimera.ChimeraXCommands;
-import jalview.gui.StructureViewer.ViewerType;
-
-/**
- * A factory that serves a class that can generate structure commands for a
- * specified structure viewer
- */
-public class StructureCommandsFactory
-{
- public StructureCommandsI getStructureCommands(ViewerType viewer)
- {
- StructureCommandsI commands = null;
- switch (viewer)
- {
- case JMOL:
- commands = new JmolCommands();
- break;
- case CHIMERA:
- commands = new ChimeraCommands();
- break;
- case CHIMERAX:
- commands = new ChimeraXCommands();
- break;
- default:
- }
- return commands;
- }
-}
public interface StructureCommandsI
{
/**
- * Data bean class to simplify parameterisation in superposeStructures
- */
- public class SuperposeData
- {
- public String filename;
-
- public String pdbId;
-
- public String chain = "";
-
- public boolean isRna;
-
- /*
- * The pdb residue number (if any) mapped to columns of the alignment
- */
- public int[] pdbResNo; // or use SparseIntArray?
-
- public int modelNo;
-
- /**
- * Constructor
- *
- * @param width
- * width of alignment (number of columns that may potentially
- * participate in superposition)
- * @param model
- * structure viewer model number
- */
- public SuperposeData(int width, int model)
- {
- pdbResNo = new int[width];
- modelNo = model;
- }
- }
-
- /**
* Returns the command to colour by chain
*
* @return
*/
- String colourByChain();
+ StructureCommandI colourByChain();
/**
* Returns the command to colour residues using a charge-based scheme:
*
* @return
*/
- String colourByCharge();
+ List<StructureCommandI> colourByCharge();
/**
* Returns the command to colour residues with the colours provided in the
* @param colours
* @return
*/
- String colourByResidues(Map<String, Color> colours);
+ List<StructureCommandI> colourByResidues(Map<String, Color> colours);
/**
* Returns the command to set the background colour of the structure viewer
* @param col
* @return
*/
- String setBackgroundColour(Color col);
+ StructureCommandI setBackgroundColour(Color col);
/**
* Returns commands to colour mapped residues of structures according to
* @return
*/
- String[] colourBySequence(Map<Object, AtomSpecModel> colourMap);
+ List<StructureCommandI> colourBySequence(
+ Map<Object, AtomSpecModel> colourMap);
/**
* Returns a command to centre the display in the structure viewer
*
* @return
*/
- String focusView();
+ StructureCommandI focusView();
/**
* Returns a command to show only the selected chains. The items in the input
- * list should be formatted as "modelno:chainid".
+ * list should be formatted as "modelid:chainid".
*
* @param toShow
* @return
*/
- String showChains(List<String> toShow);
+ List<StructureCommandI> showChains(List<String> toShow);
/**
* Returns zero, one or more commands to set attributes on mapped residues in
* @param avp
* @return
*/
- String[] setAttributesForFeatures(StructureSelectionManager ssm,
+ List<StructureCommandI> setAttributesForFeatures(
+ StructureSelectionManager ssm,
String[] files, SequenceI[][] sequence, AlignmentViewPanel avp);
/**
* @param atomSpec
* @return
*/
- String superposeStructures(AtomSpecModel refAtoms,
+ List<StructureCommandI> superposeStructures(AtomSpecModel refAtoms,
AtomSpecModel atomSpec);
/**
* @param path
* @return
*/
- String openCommandFile(String path);
+ StructureCommandI openCommandFile(String path);
/**
* Returns a command to save the current viewer session state to the given
* @param filepath
* @return
*/
- String saveSession(String filepath);
+ StructureCommandI saveSession(String filepath);
/**
* Returns a representation of the atom set represented by the model, in
int getModelStartNo();
/**
- * Show only the backbone of the peptide (cartoons in Jmol, chain in Chimera)
+ * Returns command(s) to show only the backbone of the peptide (cartoons in
+ * Jmol, chain in Chimera)
+ *
+ * @return
+ */
+ List<StructureCommandI> showBackbone();
+
+ /**
+ * Returns a command to open a file at the given path
*
+ * @param file
* @return
*/
- String showBackbone();
+ // refactor if needed to distinguish loading data or session files
+ StructureCommandI loadFile(String file);
}
import jalview.datamodel.SequenceI;
import jalview.gui.StructureViewer.ViewerType;
import jalview.io.DataSourceType;
+import jalview.io.StructureFile;
import jalview.renderer.seqfeatures.FeatureColourFinder;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ResidueProperties;
import jalview.structure.AtomSpec;
import jalview.structure.AtomSpecModel;
+import jalview.structure.StructureCommandI;
import jalview.structure.StructureCommandsI;
-import jalview.structure.StructureCommandsI.SuperposeData;
import jalview.structure.StructureListener;
import jalview.structure.StructureMapping;
import jalview.structure.StructureSelectionManager;
extends SequenceStructureBindingModel
implements StructureListener, StructureSelectionManagerProvider
{
+ /**
+ * Data bean class to simplify parameterisation in superposeStructures
+ */
+ public static class SuperposeData
+ {
+ public String filename;
+
+ public String pdbId;
+
+ public String chain = "";
+
+ public boolean isRna;
+
+ /*
+ * The pdb residue number (if any) mapped to columns of the alignment
+ */
+ public int[] pdbResNo; // or use SparseIntArray?
+
+ public String modelId;
+
+ /**
+ * Constructor
+ *
+ * @param width
+ * width of alignment (number of columns that may potentially
+ * participate in superposition)
+ * @param model
+ * structure viewer model number
+ */
+ public SuperposeData(int width, String model)
+ {
+ pdbResNo = new int[width];
+ modelId = model;
+ }
+ }
+
private static final int MIN_POS_TO_SUPERPOSE = 4;
private static final String COLOURING_STRUCTURES = MessageManager
private boolean finishedInit = false;
/**
- * current set of model filenames loaded in the Jmol instance
+ * current set of model filenames loaded in the viewer
*/
protected String[] modelFileNames = null;
* @return
*/
protected int findSuperposableResidues(AlignmentI alignment,
- BitSet matched, SuperposeData[] structures)
+ BitSet matched, AAStructureBindingModel.SuperposeData[] structures)
{
int refStructure = -1;
String[] files = getStructureFiles();
}
}
- SuperposeData[] structures = new SuperposeData[files.length];
+ AAStructureBindingModel.SuperposeData[] structures = new AAStructureBindingModel.SuperposeData[files.length];
for (int f = 0; f < files.length; f++)
{
- structures[f] = new SuperposeData(width,
- f + commandGenerator.getModelStartNo());
+ structures[f] = new AAStructureBindingModel.SuperposeData(width,
+ getModelIdForFile(files[f]));
}
/*
* Show all as backbone before doing superposition(s)
* (residues used for matching will be shown as ribbon)
*/
- executeCommand(commandGenerator.showBackbone(), false);
+ // todo better way to ensure synchronous than setting getReply true!!
+ executeCommands(commandGenerator.showBackbone(), true, null);
/*
* superpose each (other) structure to the reference in turn
if (i != refStructure)
{
AtomSpecModel atomSpec = getAtomSpec(structures[i], matched);
- String commands = commandGenerator.superposeStructures(refAtoms,
+ List<StructureCommandI> commands = commandGenerator
+ .superposeStructures(refAtoms,
atomSpec);
- List<String> replies = executeCommands(true, commands);
+ List<String> replies = executeCommands(commands, true, null);
for (String reply : replies)
{
// return this error (Chimera only) to the user
return error;
}
- private AtomSpecModel getAtomSpec(SuperposeData superposeData,
+ private AtomSpecModel getAtomSpec(AAStructureBindingModel.SuperposeData superposeData,
BitSet matched)
{
AtomSpecModel model = new AtomSpecModel();
while (nextColumnMatch != -1)
{
int pdbResNum = superposeData.pdbResNo[nextColumnMatch];
- model.addRange(superposeData.modelNo, pdbResNum, pdbResNum,
+ model.addRange(superposeData.modelId, pdbResNum, pdbResNum,
superposeData.chain);
nextColumnMatch = matched.nextSetBit(nextColumnMatch + 1);
}
{
colourBySequence = false;
- executeCommand(commandGenerator.colourByCharge(), false,
+ executeCommands(commandGenerator.colourByCharge(), false,
COLOURING_STRUCTURES);
}
/*
* pass to the command constructor, and send the command
*/
- String cmd = commandGenerator.colourByResidues(colours);
- executeCommand(cmd, false, COLOURING_STRUCTURES);
+ List<StructureCommandI> cmd = commandGenerator
+ .colourByResidues(colours);
+ executeCommands(cmd, false, COLOURING_STRUCTURES);
}
public void setBackgroundColour(Color col)
{
- String cmd = commandGenerator.setBackgroundColour(col);
+ StructureCommandI cmd = commandGenerator.setBackgroundColour(col);
executeCommand(cmd, false, null);
}
* @param msg
* @return
*/
- private List<String> executeCommand(String cmd, boolean getReply,
- String msg)
+ private List<String> executeCommand(StructureCommandI cmd,
+ boolean getReply, String msg)
{
if (getReply)
{
- return executeSynchronous(cmd, msg, getReply);
+ /*
+ * synchronous (same thread) execution so reply can be returned
+ */
+ final JalviewStructureDisplayI theViewer = getViewer();
+ final long handle = msg == null ? 0 : theViewer.startProgressBar(msg);
+ try
+ {
+ return executeCommand(cmd, getReply);
+ } finally
+ {
+ if (msg != null)
+ {
+ theViewer.stopProgressBar(null, handle);
+ }
+ }
}
else
{
- executeAsynchronous(cmd, msg);
+ /*
+ * asynchronous (new thread) execution if no reply needed
+ */
+ final JalviewStructureDisplayI theViewer = getViewer();
+ final long handle = msg == null ? 0 : theViewer.startProgressBar(msg);
+
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ executeCommand(cmd, false);
+ } finally
+ {
+ if (msg != null)
+ {
+ theViewer.stopProgressBar(null, handle);
+ }
+ }
+ }
+ });
return null;
}
}
/**
- * Sends the command in the current thread. If a message is supplied, this is
- * shown before the thread is started, and removed when it completes. May
- * return a reply to the command if requested.
+ * Execute one structure viewer command. If {@code getReply} is true, may
+ * optionally return one or more reply messages, else returns null.
*
* @param cmd
- * @param msg
* @param getReply
- * @return
*/
- private List<String> executeSynchronous(String cmd, String msg, boolean getReply)
+ protected abstract List<String> executeCommand(StructureCommandI cmd,
+ boolean getReply);
+
+ /**
+ * A helper method that converts list of commands to a vararg array
+ *
+ * @param commands
+ * @param getReply
+ * @param msg
+ */
+ private List<String> executeCommands(List<StructureCommandI> commands,
+ boolean getReply, String msg)
{
- final JalviewStructureDisplayI theViewer = getViewer();
- final long handle = msg == null ? 0 : theViewer.startProgressBar(msg);
- try
- {
- return executeCommand(cmd, getReply);
- } finally
- {
- if (msg != null)
- {
- theViewer.stopProgressBar(null, handle);
- }
- }
+ return executeCommands(getReply, msg,
+ commands.toArray(new StructureCommandI[commands.size()]));
}
/**
- * Sends the command in a separate thread. If a message is supplied, this is
- * shown before the thread is started, and removed when it completes. No value
- * is returned.
+ * Executes one or more structure viewer commands. If a progress message is
+ * provided, it is shown first, and removed after all commands have been run.
*
- * @param cmd
+ * @param getReply
* @param msg
+ * @param commands
+ * @return
*/
- private void executeAsynchronous(String cmd, String msg)
+ protected List<String> executeCommands(boolean getReply, String msg,
+ StructureCommandI[] commands)
{
+ // todo: tidy this up
+
+ /*
+ * show progress message if specified
+ */
final JalviewStructureDisplayI theViewer = getViewer();
final long handle = msg == null ? 0 : theViewer.startProgressBar(msg);
- SwingUtilities.invokeLater(new Runnable()
+ List<String> response = getReply ? new ArrayList<>() : null;
+ try
{
- @Override
- public void run()
+ for (StructureCommandI cmd : commands)
{
- try
- {
- executeCommand(cmd, false);
- } finally
+ List<String> replies = executeCommand(cmd, getReply, null);
+ if (getReply && replies != null)
{
- if (msg != null)
- {
- theViewer.stopProgressBar(null, handle);
- }
+ response.addAll(replies);
}
}
- });
- }
-
- protected abstract List<String> executeCommand(String command,
- boolean getReply);
-
- protected List<String> executeCommands(boolean getReply,
- String... commands)
- {
- // todo: tidy this up
- List<String> response = getReply ? new ArrayList<>() : null;
- for (String cmd : commands)
+ return response;
+ } finally
{
- List<String> replies = executeCommand(cmd, getReply);
- if (getReply && replies != null)
+ if (msg != null)
{
- response.addAll(replies);
+ theViewer.stopProgressBar(null, handle);
}
}
- return response;
}
/**
Map<Object, AtomSpecModel> colourMap = buildColoursMap(ssm, files,
sequence, sr, alignmentv);
- String[] colourBySequenceCommands = commandGenerator
+ List<StructureCommandI> colourBySequenceCommands = commandGenerator
.colourBySequence(colourMap);
- executeCommands(false, colourBySequenceCommands);
+ executeCommands(colourBySequenceCommands, false, null);
}
/**
*/
public void focusView()
{
- executeCommand(commandGenerator.focusView(), false);
+ executeCommand(commandGenerator.focusView(), false, null);
}
/**
if (tokens.length == 2)
{
String pdbFile = getFileForChain(chainId);
- int modelNo = getModelNoForFile(pdbFile);
- String model = modelNo == -1 ? "" : String.valueOf(modelNo);
+ String model = getModelIdForFile(pdbFile);
showThese.add(model + ":" + tokens[1]);
}
}
- executeCommand(commandGenerator.showChains(showThese), false);
+ executeCommands(commandGenerator.showChains(showThese), false, null);
}
/**
- * Answers the structure viewer's model number given a PDB file name. Returns
- * -1 if model number is not found.
+ * Answers the structure viewer's model id given a PDB file name. Returns an
+ * empty string if model id is not found.
*
* @param chainId
* @return
*/
- protected abstract int getModelNoForFile(String chainId);
+ protected abstract String getModelIdForFile(String chainId);
public boolean hasFileLoadingError()
{
* @param command
* @param progressMsg
*/
- protected void sendAsynchronousCommand(String command, String progressMsg)
+ protected void sendAsynchronousCommand(StructureCommandI command,
+ String progressMsg)
{
final JalviewStructureDisplayI theViewer = getViewer();
final long handle = progressMsg == null ? 0
{
try
{
- executeCommand(command, false);
+ executeCommand(command, false, null);
} finally
{
if (progressMsg != null)
* {@code AtomSpecModel}, where the atomspec model holds
*
* <pre>
- * Model numbers
+ * Model ids
* Chains
* Residue positions
* </pre>
for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
- final int modelNumber = pdbfnum + commandGenerator.getModelStartNo();
+ // todo indirect this resolution / allow override
+ final String modelId = getModelIdForFile(files[pdbfnum]);
StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
if (mapping == null || mapping.length < 1)
{
if (startPos != -1)
{
- addAtomSpecRange(colourMap, lastColour, modelNumber,
+ addAtomSpecRange(colourMap, lastColour, modelId,
startPos, lastPos, lastChain);
}
startPos = pos;
// final colour range
if (lastColour != null)
{
- addAtomSpecRange(colourMap, lastColour, modelNumber, startPos,
+ addAtomSpecRange(colourMap, lastColour, modelId, startPos,
lastPos, lastChain);
}
// break;
}
/**
+ * todo better refactoring (map lookup or similar to get viewer structure id)
+ *
+ * @param pdbfnum
+ * @param file
+ * @return
+ */
+ protected String getModelId(int pdbfnum, String file)
+ {
+ return String.valueOf(pdbfnum);
+ }
+
+ /**
+ * Saves chains, formatted as "pdbId:chainCode", and lookups from this to the
+ * full PDB file path
+ *
+ * @param pdb
+ * @param file
+ */
+ public void stashFoundChains(StructureFile pdb, String file)
+ {
+ for (int i = 0; i < pdb.getChains().size(); i++)
+ {
+ String chid = pdb.getId() + ":" + pdb.getChains().elementAt(i).id;
+ addChainFile(chid, file);
+ getChainNames().add(chid);
+ }
+ }
+
+ /**
* Helper method to add one contiguous range to the AtomSpec model for the given
* value (creating the model if necessary). As used by Jalview, {@code value} is
* <ul>
*/
public static final void addAtomSpecRange(Map<Object, AtomSpecModel> map,
Object value,
- int model, int startPos, int endPos, String chain)
+ String model, int startPos, int endPos, String chain)
{
/*
* Get/initialize map of data for the colour
import jalview.gui.SequenceRenderer;
import jalview.schemes.JalviewColourScheme;
import jalview.structure.AtomSpecModel;
+import jalview.structure.StructureCommandI;
import jalview.structure.StructureCommandsI;
import jalview.structure.StructureMapping;
import jalview.structure.StructureSelectionManager;
import java.awt.Color;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import org.testng.annotations.BeforeClass;
StructureCommandsI testee = new JmolCommands();
AtomSpecModel model = new AtomSpecModel();
assertEquals(testee.getAtomSpec(model, false), "");
- model.addRange(1, 2, 4, "A");
+ model.addRange("1", 2, 4, "A");
assertEquals(testee.getAtomSpec(model, false), "2-4:A/1.1");
- model.addRange(1, 8, 8, "A");
+ model.addRange("1", 8, 8, "A");
assertEquals(testee.getAtomSpec(model, false), "2-4:A/1.1|8:A/1.1");
- model.addRange(1, 5, 7, "B");
+ model.addRange("1", 5, 7, "B");
assertEquals(testee.getAtomSpec(model, false),
"2-4:A/1.1|8:A/1.1|5-7:B/1.1");
- model.addRange(1, 3, 5, "A");
+ model.addRange("1", 3, 5, "A");
assertEquals(testee.getAtomSpec(model, false),
"2-5:A/1.1|8:A/1.1|5-7:B/1.1");
- model.addRange(2, 1, 4, "B");
+ model.addRange("2", 1, 4, "B");
assertEquals(testee.getAtomSpec(model, false),
"2-5:A/1.1|8:A/1.1|5-7:B/1.1|1-4:B/2.1");
- model.addRange(2, 5, 9, "C");
+ model.addRange("2", 5, 9, "C");
assertEquals(testee.getAtomSpec(model, false),
"2-5:A/1.1|8:A/1.1|5-7:B/1.1|1-4:B/2.1|5-9:C/2.1");
- model.addRange(1, 8, 10, "B");
+ model.addRange("1", 8, 10, "B");
assertEquals(testee.getAtomSpec(model, false),
"2-5:A/1.1|8:A/1.1|5-10:B/1.1|1-4:B/2.1|5-9:C/2.1");
- model.addRange(1, 8, 9, "B");
+ model.addRange("1", 8, 9, "B");
assertEquals(testee.getAtomSpec(model, false),
"2-5:A/1.1|8:A/1.1|5-10:B/1.1|1-4:B/2.1|5-9:C/2.1");
- model.addRange(2, 3, 10, "C"); // subsumes 5-9
+ model.addRange("2", 3, 10, "C"); // subsumes 5-9
assertEquals(testee.getAtomSpec(model, false),
"2-5:A/1.1|8:A/1.1|5-10:B/1.1|1-4:B/2.1|3-10:C/2.1");
- model.addRange(5, 25, 35, " ");
+ model.addRange("5", 25, 35, " ");
assertEquals(testee.getAtomSpec(model, false),
"2-5:A/1.1|8:A/1.1|5-10:B/1.1|1-4:B/2.1|3-10:C/2.1|25-35:/5.1");
public void testColourBySequence()
{
Map<Object, AtomSpecModel> map = new LinkedHashMap<>();
- JmolCommands.addAtomSpecRange(map, Color.blue, 1, 2, 5, "A");
- JmolCommands.addAtomSpecRange(map, Color.blue, 1, 7, 7, "B");
- JmolCommands.addAtomSpecRange(map, Color.blue, 1, 9, 23, "A");
- JmolCommands.addAtomSpecRange(map, Color.blue, 2, 1, 1, "A");
- JmolCommands.addAtomSpecRange(map, Color.blue, 2, 4, 7, "B");
- JmolCommands.addAtomSpecRange(map, Color.yellow, 2, 8, 8, "A");
- JmolCommands.addAtomSpecRange(map, Color.yellow, 2, 3, 5, "A");
- JmolCommands.addAtomSpecRange(map, Color.red, 1, 3, 5, "A");
- JmolCommands.addAtomSpecRange(map, Color.red, 1, 6, 9, "A");
+ JmolCommands.addAtomSpecRange(map, Color.blue, "1", 2, 5, "A");
+ JmolCommands.addAtomSpecRange(map, Color.blue, "1", 7, 7, "B");
+ JmolCommands.addAtomSpecRange(map, Color.blue, "1", 9, 23, "A");
+ JmolCommands.addAtomSpecRange(map, Color.blue, "2", 1, 1, "A");
+ JmolCommands.addAtomSpecRange(map, Color.blue, "2", 4, 7, "B");
+ JmolCommands.addAtomSpecRange(map, Color.yellow, "2", 8, 8, "A");
+ JmolCommands.addAtomSpecRange(map, Color.yellow, "2", 3, 5, "A");
+ JmolCommands.addAtomSpecRange(map, Color.red, "1", 3, 5, "A");
+ JmolCommands.addAtomSpecRange(map, Color.red, "1", 6, 9, "A");
// Colours should appear in the Jmol command in the order in which
// they were added; within colour, by model, by chain, ranges in start order
- String[] commands = new JmolCommands().colourBySequence(map);
- assertEquals(commands.length, 1);
- String expected = "select 2-5:A/1.1|9-23:A/1.1|7:B/1.1|1:A/2.1|4-7:B/2.1;color[0,0,255]; "
- + "select 3-5:A/2.1|8:A/2.1;color[255,255,0]; "
- + "select 3-9:A/1.1;color[255,0,0]";
- assertEquals(commands[0], expected);
+ List<StructureCommandI> commands = new JmolCommands()
+ .colourBySequence(map);
+ assertEquals(commands.size(), 3);
+ String expected1 = "select 2-5:A/1.1|9-23:A/1.1|7:B/1.1|1:A/2.1|4-7:B/2.1;color[0,0,255]";
+ String expected2 = "select 3-5:A/2.1|8:A/2.1;color[255,255,0]";
+ String expected3 = "select 3-9:A/1.1;color[255,0,0]";
+ assertEquals(commands.get(0).getCommand(), expected1);
+ assertEquals(commands.get(1).getCommand(), expected2);
+ assertEquals(commands.get(2).getCommand(), expected3);
}
@Test(groups = { "Functional" })
{
StructureCommandsI testee = new JmolCommands();
AtomSpecModel ref = new AtomSpecModel();
- ref.addRange(1, 12, 14, "A");
- ref.addRange(1, 18, 18, "B");
- ref.addRange(1, 22, 23, "B");
+ ref.addRange("1", 12, 14, "A");
+ ref.addRange("1", 18, 18, "B");
+ ref.addRange("1", 22, 23, "B");
AtomSpecModel toAlign = new AtomSpecModel();
- toAlign.addRange(2, 15, 17, "B");
- toAlign.addRange(2, 20, 21, "B");
- toAlign.addRange(2, 22, 22, "C");
- String command = testee.superposeStructures(ref, toAlign);
+ toAlign.addRange("2", 15, 17, "B");
+ toAlign.addRange("2", 20, 21, "B");
+ toAlign.addRange("2", 22, 22, "C");
+ List<StructureCommandI> command = testee.superposeStructures(ref,
+ toAlign);
+ assertEquals(command.size(), 1);
String refSpec = "12-14:A/1.1|18:B/1.1|22-23:B/1.1";
String toAlignSpec = "15-17:B/2.1|20-21:B/2.1|22:C/2.1";
String expected = String.format(
"compare {2.1} {1.1} SUBSET {(*.CA | *.P) and conformation=1} ATOMS {%s}{%s} ROTATE TRANSLATE ;select %s|%s;cartoons",
toAlignSpec, refSpec, toAlignSpec, refSpec);
- assertEquals(command, expected);
+ assertEquals(command.get(0).getCommand(), expected);
}
@Test(groups = "Functional")
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ext.pymol;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.structure.AtomSpecModel;
+import jalview.structure.StructureCommandI;
+import jalview.structure.StructureCommandsI;
+
+import java.awt.Color;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+public class PymolCommandsTest
+{
+
+ @Test(groups = { "Functional" })
+ public void testColourBySequence()
+ {
+
+ Map<Object, AtomSpecModel> map = new LinkedHashMap<>();
+ PymolCommands.addAtomSpecRange(map, Color.blue, "0", 2, 5, "A");
+ PymolCommands.addAtomSpecRange(map, Color.blue, "0", 7, 7, "B");
+ PymolCommands.addAtomSpecRange(map, Color.blue, "0", 9, 23, "A");
+ PymolCommands.addAtomSpecRange(map, Color.blue, "1", 1, 1, "A");
+ PymolCommands.addAtomSpecRange(map, Color.blue, "1", 4, 7, "B");
+ PymolCommands.addAtomSpecRange(map, Color.yellow, "1", 8, 8, "A");
+ PymolCommands.addAtomSpecRange(map, Color.yellow, "1", 3, 5, "A");
+ PymolCommands.addAtomSpecRange(map, Color.red, "0", 3, 5, "A");
+ PymolCommands.addAtomSpecRange(map, Color.red, "0", 6, 9, "A");
+
+ // Colours should appear in the Pymol command in the order in which
+ // they were added; within colour, by model, by chain, ranges in start order
+ List<StructureCommandI> commands = new PymolCommands()
+ .colourBySequence(map);
+ assertEquals(commands.size(), 3);
+ assertEquals(commands.get(0).toString(),
+ "color(0x0000ff,0//A/2-5+9-23/ 0//B/7/ 1//A/1/ 1//B/4-7/)");
+ assertEquals(commands.get(1).toString(), "color(0xffff00,1//A/3-5+8/)");
+ assertEquals(
+ commands.get(2).toString(), "color(0xff0000,0//A/3-9/)");
+ }
+
+ @Test(groups = "Functional")
+ public void testGetAtomSpec()
+ {
+ StructureCommandsI testee = new PymolCommands();
+ AtomSpecModel model = new AtomSpecModel();
+ assertEquals(testee.getAtomSpec(model, false), "");
+ model.addRange("1", 2, 4, "A");
+ assertEquals(testee.getAtomSpec(model, false), "1//A/2-4/");
+ model.addRange("1", 8, 8, "A");
+ assertEquals(testee.getAtomSpec(model, false), "1//A/2-4+8/");
+ model.addRange("1", 5, 7, "B");
+ assertEquals(testee.getAtomSpec(model, false), "1//A/2-4+8/ 1//B/5-7/");
+ model.addRange("1", 3, 5, "A");
+ assertEquals(testee.getAtomSpec(model, false), "1//A/2-5+8/ 1//B/5-7/");
+ model.addRange("0", 1, 4, "B");
+ assertEquals(testee.getAtomSpec(model, false),
+ "0//B/1-4/ 1//A/2-5+8/ 1//B/5-7/");
+ model.addRange("0", 5, 9, "C");
+ assertEquals(testee.getAtomSpec(model, false),
+ "0//B/1-4/ 0//C/5-9/ 1//A/2-5+8/ 1//B/5-7/");
+ model.addRange("1", 8, 10, "B");
+ assertEquals(testee.getAtomSpec(model, false),
+ "0//B/1-4/ 0//C/5-9/ 1//A/2-5+8/ 1//B/5-10/");
+ model.addRange("1", 8, 9, "B");
+ assertEquals(testee.getAtomSpec(model, false),
+ "0//B/1-4/ 0//C/5-9/ 1//A/2-5+8/ 1//B/5-10/");
+ model.addRange("0", 3, 10, "C"); // subsumes 5-9
+ assertEquals(testee.getAtomSpec(model, false),
+ "0//B/1-4/ 0//C/3-10/ 1//A/2-5+8/ 1//B/5-10/");
+ model.addRange("5", 25, 35, " ");
+ assertEquals(testee.getAtomSpec(model, false),
+ "0//B/1-4/ 0//C/3-10/ 1//A/2-5+8/ 1//B/5-10/ 5///25-35/");
+
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSuperposeStructures()
+ {
+ StructureCommandsI testee = new PymolCommands();
+ AtomSpecModel ref = new AtomSpecModel();
+ ref.addRange("1", 12, 14, "A");
+ ref.addRange("1", 18, 18, "B");
+ ref.addRange("1", 22, 23, "B");
+ AtomSpecModel toAlign = new AtomSpecModel();
+ toAlign.addRange("2", 15, 17, "B");
+ toAlign.addRange("2", 20, 21, "B");
+ toAlign.addRange("2", 22, 22, "C");
+ List<StructureCommandI> commands = testee.superposeStructures(ref,
+ toAlign);
+ assertEquals(commands.size(), 2);
+ String refSpecCA = "1//A/12-14/CA 1//B/18+22-23/CA";
+ String toAlignSpecCA = "2//B/15-17+20-21/CA 2//C/22/CA";
+ String refSpec = "1//A/12-14/ 1//B/18+22-23/";
+ String toAlignSpec = "2//B/15-17+20-21/ 2//C/22/";
+ String expected1 = String.format("super(%s,%s)", refSpecCA,
+ toAlignSpecCA);
+ String expected2 = String.format("show(cartoon,%s %s)", refSpec,
+ toAlignSpec);
+ assertEquals(commands.get(0).toString(), expected1);
+ assertEquals(commands.get(1).toString(), expected2);
+ }
+
+ @Test(groups = "Functional")
+ public void testGetAtomSpec_alphaOnly()
+ {
+ StructureCommandsI testee = new PymolCommands();
+ AtomSpecModel model = new AtomSpecModel();
+ assertEquals(testee.getAtomSpec(model, true), "");
+ model.addRange("1", 2, 4, "A");
+ assertEquals(testee.getAtomSpec(model, true), "1//A/2-4/CA");
+ model.addRange("1", 8, 8, "A");
+ assertEquals(testee.getAtomSpec(model, true), "1//A/2-4+8/CA");
+ model.addRange("1", 5, 7, "B");
+ assertEquals(testee.getAtomSpec(model, true),
+ "1//A/2-4+8/CA 1//B/5-7/CA");
+ model.addRange("1", 3, 5, "A");
+ assertEquals(testee.getAtomSpec(model, true),
+ "1//A/2-5+8/CA 1//B/5-7/CA");
+ model.addRange("0", 1, 4, "B");
+ assertEquals(testee.getAtomSpec(model, true),
+ "0//B/1-4/CA 1//A/2-5+8/CA 1//B/5-7/CA");
+ model.addRange("0", 5, 9, "C");
+ assertEquals(testee.getAtomSpec(model, true),
+ "0//B/1-4/CA 0//C/5-9/CA 1//A/2-5+8/CA 1//B/5-7/CA");
+ model.addRange("1", 8, 10, "B");
+ assertEquals(testee.getAtomSpec(model, true),
+ "0//B/1-4/CA 0//C/5-9/CA 1//A/2-5+8/CA 1//B/5-10/CA");
+ model.addRange("1", 8, 9, "B");
+ assertEquals(testee.getAtomSpec(model, true),
+ "0//B/1-4/CA 0//C/5-9/CA 1//A/2-5+8/CA 1//B/5-10/CA");
+ model.addRange("0", 3, 10, "C"); // subsumes 5-9
+ assertEquals(testee.getAtomSpec(model, true),
+ "0//B/1-4/CA 0//C/3-10/CA 1//A/2-5+8/CA 1//B/5-10/CA");
+ model.addRange("5", 25, 35, " ");
+ assertEquals(testee.getAtomSpec(model, true),
+ "0//B/1-4/CA 0//C/3-10/CA 1//A/2-5+8/CA 1//B/5-10/CA 5///25-35/CA");
+ }
+
+ @Test(groups = "Functional")
+ public void testGetModelStartNo()
+ {
+ StructureCommandsI testee = new PymolCommands();
+ assertEquals(testee.getModelStartNo(), 0);
+ }
+
+ @Test(groups = "Functional")
+ public void testGetResidueSpec()
+ {
+ PymolCommands testee = new PymolCommands();
+ assertEquals(testee.getResidueSpec("ALA"), "resn ALA");
+ }
+
+ @Test(groups = "Functional")
+ public void testShowBackbone()
+ {
+ PymolCommands testee = new PymolCommands();
+ List<StructureCommandI> cmds = testee.showBackbone();
+ assertEquals(cmds.size(), 2);
+ assertEquals(cmds.get(0).toString(), "hide(everything)");
+ assertEquals(cmds.get(1).toString(), "show(ribbon)");
+ }
+
+ @Test(groups = "Functional")
+ public void testOpenCommandFile()
+ {
+ PymolCommands testee = new PymolCommands();
+ assertEquals(testee.openCommandFile("commands.pml").toString(),
+ "@commands.pml");
+ }
+
+ @Test(groups = "Functional")
+ public void testSaveSession()
+ {
+ PymolCommands testee = new PymolCommands();
+ assertEquals(testee.saveSession("somewhere.pse").toString(),
+ "save(somewhere.pse)");
+ }
+
+ @Test(groups = "Functional")
+ public void testGetColourCommand()
+ {
+ PymolCommands testee = new PymolCommands();
+ assertEquals(
+ testee.getColourCommand("something", Color.MAGENTA).toString(),
+ "color(0xff00ff,something)");
+ }
+}
--- /dev/null
+package jalview.ext.pymol;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.structure.StructureCommand;
+
+import org.testng.annotations.Test;
+
+public class PymolManagerTest
+{
+ @Test(groups = "Functional")
+ public void testGetPostRequest()
+ {
+ String req = PymolManager
+ .getPostRequest(new StructureCommand("foobar"));
+ assertEquals(req,
+ "<methodCall><methodName>foobar</methodName><params></params></methodCall>");
+
+ req = PymolManager
+ .getPostRequest(new StructureCommand("foobar", "blue", "all"));
+ assertEquals(req, "<methodCall><methodName>foobar</methodName><params>"
+ + "<parameter><value>blue</value></parameter>"
+ + "<parameter><value>all</value></parameter>"
+ + "</params></methodCall>");
+ }
+}
import static org.testng.Assert.assertTrue;
import jalview.structure.AtomSpecModel;
+import jalview.structure.StructureCommandI;
import jalview.structure.StructureCommandsI;
import java.awt.Color;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import org.testng.annotations.Test;
{
Map<Object, AtomSpecModel> map = new LinkedHashMap<>();
- ChimeraCommands.addAtomSpecRange(map, Color.blue, 0, 2, 5, "A");
- ChimeraCommands.addAtomSpecRange(map, Color.blue, 0, 7, 7, "B");
- ChimeraCommands.addAtomSpecRange(map, Color.blue, 0, 9, 23, "A");
- ChimeraCommands.addAtomSpecRange(map, Color.blue, 1, 1, 1, "A");
- ChimeraCommands.addAtomSpecRange(map, Color.blue, 1, 4, 7, "B");
- ChimeraCommands.addAtomSpecRange(map, Color.yellow, 1, 8, 8, "A");
- ChimeraCommands.addAtomSpecRange(map, Color.yellow, 1, 3, 5, "A");
- ChimeraCommands.addAtomSpecRange(map, Color.red, 0, 3, 5, "A");
- ChimeraCommands.addAtomSpecRange(map, Color.red, 0, 6, 9, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.blue, "0", 2, 5, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.blue, "0", 7, 7, "B");
+ ChimeraCommands.addAtomSpecRange(map, Color.blue, "0", 9, 23, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.blue, "1", 1, 1, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.blue, "1", 4, 7, "B");
+ ChimeraCommands.addAtomSpecRange(map, Color.yellow, "1", 8, 8, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.yellow, "1", 3, 5, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.red, "0", 3, 5, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.red, "0", 6, 9, "A");
// Colours should appear in the Chimera command in the order in which
// they were added; within colour, by model, by chain, ranges in start order
- String[] commands = new ChimeraCommands().colourBySequence(map);
- assertEquals(commands.length, 1);
- assertEquals(
- commands[0],
- "color #0000ff #0:2-5.A,9-23.A,7.B|#1:1.A,4-7.B; color #ffff00 #1:3-5.A,8.A; color #ff0000 #0:3-9.A");
+ List<StructureCommandI> commands = new ChimeraCommands()
+ .colourBySequence(map);
+ assertEquals(commands.size(), 3);
+ assertEquals(commands.get(0).getCommand(),
+ "color #0000ff #0:2-5.A,9-23.A,7.B|#1:1.A,4-7.B");
+ assertEquals(commands.get(1).getCommand(),
+ "color #ffff00 #1:3-5.A,8.A");
+ assertEquals(commands.get(2).getCommand(), "color #ff0000 #0:3-9.A");
}
@Test(groups = { "Functional" })
* start with just one feature/value...
*/
featuresMap.put("chain", featureValues);
- ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 8, 20, "A");
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 8, 20, "A");
ChimeraCommands commandGenerator = new ChimeraCommands();
- String[] commands = commandGenerator.setAttributes(featuresMap);
- assertEquals(1, commands.length);
+ List<StructureCommandI> commands = commandGenerator
+ .setAttributes(featuresMap);
+ assertEquals(1, commands.size());
/*
* feature name gets a jv_ namespace prefix
* feature value is quoted in case it contains spaces
*/
- assertEquals(commands[0], "setattr res jv_chain 'X' #0:8-20.A");
+ assertEquals(commands.get(0).getCommand(),
+ "setattr res jv_chain 'X' #0:8-20.A");
// add same feature value, overlapping range
- ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 3, 9, "A");
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 3, 9, "A");
// same feature value, contiguous range
- ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 21, 25, "A");
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 21, 25, "A");
commands = commandGenerator.setAttributes(featuresMap);
- assertEquals(1, commands.length);
- assertEquals(commands[0], "setattr res jv_chain 'X' #0:3-25.A");
+ assertEquals(1, commands.size());
+ assertEquals(commands.get(0).getCommand(),
+ "setattr res jv_chain 'X' #0:3-25.A");
// same feature value and model, different chain
- ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 21, 25, "B");
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 21, 25, "B");
// same feature value and chain, different model
- ChimeraCommands.addAtomSpecRange(featureValues, "X", 1, 26, 30, "A");
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "1", 26, 30, "A");
commands = commandGenerator.setAttributes(featuresMap);
- assertEquals(1, commands.length);
+ assertEquals(1, commands.size());
String expected1 = "setattr res jv_chain 'X' #0:3-25.A,21-25.B|#1:26-30.A";
- assertEquals(commands[0],
- expected1);
+ assertEquals(commands.get(0).getCommand(), expected1);
// same feature, different value
- ChimeraCommands.addAtomSpecRange(featureValues, "Y", 0, 40, 50, "A");
+ ChimeraCommands.addAtomSpecRange(featureValues, "Y", "0", 40, 50, "A");
commands = commandGenerator.setAttributes(featuresMap);
- assertEquals(2, commands.length);
+ assertEquals(2, commands.size());
// commands are ordered by feature type but not by value
// so test for the expected command in either order
- assertTrue(
- commands[0].equals(expected1) || commands[1].equals(expected1));
+ String cmd1 = commands.get(0).getCommand();
+ String cmd2 = commands.get(1).getCommand();
+ assertTrue(cmd1.equals(expected1) || cmd2.equals(expected1));
String expected2 = "setattr res jv_chain 'Y' #0:40-50.A";
- assertTrue(
- commands[0].equals(expected2) || commands[1].equals(expected2));
+ assertTrue(cmd1.equals(expected2) || cmd2.equals(expected2));
featuresMap.clear();
featureValues.clear();
featuresMap.put("side-chain binding!", featureValues);
ChimeraCommands.addAtomSpecRange(featureValues,
- "<html>metal <a href=\"http:a.b.c/x\"> 'ion!", 0, 7, 15,
+ "<html>metal <a href=\"http:a.b.c/x\"> 'ion!", "0", 7, 15,
"A");
// feature names are sanitised to change non-alphanumeric to underscore
// feature values are sanitised to encode single quote characters
commands = commandGenerator.setAttributes(featuresMap);
+ assertEquals(commands.size(), 1);
String expected3 = "setattr res jv_side_chain_binding_ '<html>metal <a href=\"http:a.b.c/x\"> 'ion!' #0:7-15.A";
- assertTrue(
- commands[0].equals(expected3) || commands[1].equals(expected3));
+ assertTrue(commands.get(0).getCommand().equals(expected3));
}
/**
StructureCommandsI testee = new ChimeraCommands();
AtomSpecModel model = new AtomSpecModel();
assertEquals(testee.getAtomSpec(model, false), "");
- model.addRange(1, 2, 4, "A");
+ model.addRange("1", 2, 4, "A");
assertEquals(testee.getAtomSpec(model, false), "#1:2-4.A");
- model.addRange(1, 8, 8, "A");
+ model.addRange("1", 8, 8, "A");
assertEquals(testee.getAtomSpec(model, false), "#1:2-4.A,8.A");
- model.addRange(1, 5, 7, "B");
+ model.addRange("1", 5, 7, "B");
assertEquals(testee.getAtomSpec(model, false), "#1:2-4.A,8.A,5-7.B");
- model.addRange(1, 3, 5, "A");
+ model.addRange("1", 3, 5, "A");
assertEquals(testee.getAtomSpec(model, false), "#1:2-5.A,8.A,5-7.B");
- model.addRange(0, 1, 4, "B");
+ model.addRange("0", 1, 4, "B");
assertEquals(testee.getAtomSpec(model, false),
"#0:1-4.B|#1:2-5.A,8.A,5-7.B");
- model.addRange(0, 5, 9, "C");
+ model.addRange("0", 5, 9, "C");
assertEquals(testee.getAtomSpec(model, false),
"#0:1-4.B,5-9.C|#1:2-5.A,8.A,5-7.B");
- model.addRange(1, 8, 10, "B");
+ model.addRange("1", 8, 10, "B");
assertEquals(testee.getAtomSpec(model, false),
"#0:1-4.B,5-9.C|#1:2-5.A,8.A,5-10.B");
- model.addRange(1, 8, 9, "B");
+ model.addRange("1", 8, 9, "B");
assertEquals(testee.getAtomSpec(model, false),
"#0:1-4.B,5-9.C|#1:2-5.A,8.A,5-10.B");
- model.addRange(0, 3, 10, "C"); // subsumes 5-9
+ model.addRange("0", 3, 10, "C"); // subsumes 5-9
assertEquals(testee.getAtomSpec(model, false),
"#0:1-4.B,3-10.C|#1:2-5.A,8.A,5-10.B");
- model.addRange(5, 25, 35, " "); // empty chain code - e.g. from homology
- // modelling
+ model.addRange("5", 25, 35, " ");
assertEquals(testee.getAtomSpec(model, false),
"#0:1-4.B,3-10.C|#1:2-5.A,8.A,5-10.B|#5:25-35.");
{
StructureCommandsI testee = new ChimeraCommands();
AtomSpecModel ref = new AtomSpecModel();
- ref.addRange(1, 12, 14, "A");
- ref.addRange(1, 18, 18, "B");
- ref.addRange(1, 22, 23, "B");
+ ref.addRange("1", 12, 14, "A");
+ ref.addRange("1", 18, 18, "B");
+ ref.addRange("1", 22, 23, "B");
AtomSpecModel toAlign = new AtomSpecModel();
- toAlign.addRange(2, 15, 17, "B");
- toAlign.addRange(2, 20, 21, "B");
- toAlign.addRange(2, 22, 22, "C");
- String command = testee.superposeStructures(ref, toAlign);
+ toAlign.addRange("2", 15, 17, "B");
+ toAlign.addRange("2", 20, 21, "B");
+ toAlign.addRange("2", 22, 22, "C");
+ List<StructureCommandI> command = testee.superposeStructures(ref,
+ toAlign);
String refSpec = "#1:12-14.A,18.B,22-23.B@CA|P&~@.B-Z&~@.2-9";
String toAlignSpec = "#2:15-17.B,20-21.B,22.C@CA|P&~@.B-Z&~@.2-9";
String expected = String.format(
- "match %s %s;~display all; chain @CA|P; ribbon %s|%s; focus",
+ "match %s %s; ribbon %s|%s; focus",
refSpec, toAlignSpec, refSpec, toAlignSpec);
- assertEquals(command, expected);
+ assertEquals(command.get(0).getCommand(), expected);
}
@Test(groups = "Functional")
StructureCommandsI testee = new ChimeraCommands();
AtomSpecModel model = new AtomSpecModel();
assertEquals(testee.getAtomSpec(model, true), "");
- model.addRange(1, 2, 4, "A");
+ model.addRange("1", 2, 4, "A");
assertEquals(testee.getAtomSpec(model, true),
"#1:2-4.A@CA|P&~@.B-Z&~@.2-9");
- model.addRange(1, 8, 8, "A");
+ model.addRange("1", 8, 8, "A");
assertEquals(testee.getAtomSpec(model, true),
"#1:2-4.A,8.A@CA|P&~@.B-Z&~@.2-9");
- model.addRange(1, 5, 7, "B");
+ model.addRange("1", 5, 7, "B");
assertEquals(testee.getAtomSpec(model, true),
"#1:2-4.A,8.A,5-7.B@CA|P&~@.B-Z&~@.2-9");
- model.addRange(1, 3, 5, "A");
+ model.addRange("1", 3, 5, "A");
assertEquals(testee.getAtomSpec(model, true),
"#1:2-5.A,8.A,5-7.B@CA|P&~@.B-Z&~@.2-9");
- model.addRange(0, 1, 4, "B");
+ model.addRange("0", 1, 4, "B");
assertEquals(testee.getAtomSpec(model, true),
"#0:1-4.B@CA|P&~@.B-Z&~@.2-9|#1:2-5.A,8.A,5-7.B@CA|P&~@.B-Z&~@.2-9");
- model.addRange(0, 5, 9, "C");
+ model.addRange("0", 5, 9, "C");
assertEquals(testee.getAtomSpec(model, true),
"#0:1-4.B,5-9.C@CA|P&~@.B-Z&~@.2-9|#1:2-5.A,8.A,5-7.B@CA|P&~@.B-Z&~@.2-9");
- model.addRange(1, 8, 10, "B");
+ model.addRange("1", 8, 10, "B");
assertEquals(testee.getAtomSpec(model, true),
"#0:1-4.B,5-9.C@CA|P&~@.B-Z&~@.2-9|#1:2-5.A,8.A,5-10.B@CA|P&~@.B-Z&~@.2-9");
- model.addRange(1, 8, 9, "B");
+ model.addRange("1", 8, 9, "B");
assertEquals(testee.getAtomSpec(model, true),
"#0:1-4.B,5-9.C@CA|P&~@.B-Z&~@.2-9|#1:2-5.A,8.A,5-10.B@CA|P&~@.B-Z&~@.2-9");
- model.addRange(0, 3, 10, "C"); // subsumes 5-9
+ model.addRange("0", 3, 10, "C"); // subsumes 5-9
assertEquals(testee.getAtomSpec(model, true),
"#0:1-4.B,3-10.C@CA|P&~@.B-Z&~@.2-9|#1:2-5.A,8.A,5-10.B@CA|P&~@.B-Z&~@.2-9");
- model.addRange(5, 25, 35, " "); // empty chain code
+ model.addRange("5", 25, 35, " "); // empty chain code
assertEquals(testee.getAtomSpec(model, true),
"#0:1-4.B,3-10.C@CA|P&~@.B-Z&~@.2-9|#1:2-5.A,8.A,5-10.B@CA|P&~@.B-Z&~@.2-9|#5:25-35.@CA|P&~@.B-Z&~@.2-9");
public void testShowBackbone()
{
ChimeraCommands testee = new ChimeraCommands();
- assertEquals(testee.showBackbone(), "~display all;chain @CA|P");
+ List<StructureCommandI> cmds = testee.showBackbone();
+ assertEquals(cmds.size(), 1);
+ assertEquals(cmds.get(0).getCommand(), "~display all;chain @CA|P");
}
@Test(groups = "Functional")
public void testOpenCommandFile()
{
ChimeraCommands testee = new ChimeraCommands();
- assertEquals(testee.openCommandFile("nowhere"), "open cmd:nowhere");
+ assertEquals(testee.openCommandFile("nowhere").getCommand(),
+ "open cmd:nowhere");
}
@Test(groups = "Functional")
public void testSaveSession()
{
ChimeraCommands testee = new ChimeraCommands();
- assertEquals(testee.saveSession("somewhere"), "save somewhere");
+ assertEquals(testee.saveSession("somewhere").getCommand(),
+ "save somewhere");
}
@Test(groups = "Functional")
public void testGetColourCommand()
{
ChimeraCommands testee = new ChimeraCommands();
- assertEquals(testee.getColourCommand("something", Color.MAGENTA),
+ assertEquals(testee.getColourCommand("something", Color.MAGENTA)
+ .getCommand(),
"color #ff00ff something");
}
{
ChimeraCommands testee = new ChimeraCommands();
AtomSpecModel model = new AtomSpecModel();
- model.addRange(1, 89, 92, "A");
- model.addRange(2, 12, 20, "B");
- model.addRange(2, 8, 9, "B");
- assertEquals(testee.setAttribute("phi", "27.3", model),
+ model.addRange("1", 89, 92, "A");
+ model.addRange("2", 12, 20, "B");
+ model.addRange("2", 8, 9, "B");
+ assertEquals(testee.setAttribute("phi", "27.3", model).getCommand(),
"setattr res phi '27.3' #1:89-92.A|#2:8-9.B,12-20.B");
}
}
import static org.testng.Assert.assertTrue;
import jalview.structure.AtomSpecModel;
+import jalview.structure.StructureCommandI;
import jalview.structure.StructureCommandsI;
import java.awt.Color;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import org.testng.annotations.Test;
@Test(groups = { "Functional" })
public void testColourByCharge()
{
- String cmd = new ChimeraXCommands().colourByCharge();
- assertEquals(cmd,
+ List<StructureCommandI> cmd = new ChimeraXCommands().colourByCharge();
+ assertEquals(cmd.size(), 1);
+ assertEquals(cmd.get(0).getCommand(),
"color white;color :ASP,GLU red;color :LYS,ARG blue;color :CYS yellow");
}
@Test(groups = { "Functional" })
public void testColourByChain()
{
- String cmd = new ChimeraXCommands().colourByChain();
- assertEquals(cmd, "rainbow chain");
+ StructureCommandI cmd = new ChimeraXCommands().colourByChain();
+ assertEquals(cmd.getCommand(), "rainbow chain");
}
@Test(groups = { "Functional" })
public void testFocusView()
{
- String cmd = new ChimeraXCommands().focusView();
- assertEquals(cmd, "view");
+ StructureCommandI cmd = new ChimeraXCommands().focusView();
+ assertEquals(cmd.getCommand(), "view");
}
@Test(groups = { "Functional" })
public void testColourBySequence()
{
Map<Object, AtomSpecModel> map = new LinkedHashMap<>();
- ChimeraCommands.addAtomSpecRange(map, Color.blue, 1, 2, 5, "A");
- ChimeraCommands.addAtomSpecRange(map, Color.blue, 1, 7, 7, "B");
- ChimeraCommands.addAtomSpecRange(map, Color.blue, 1, 9, 23, "A");
- ChimeraCommands.addAtomSpecRange(map, Color.blue, 2, 1, 1, "A");
- ChimeraCommands.addAtomSpecRange(map, Color.blue, 2, 4, 7, "B");
- ChimeraCommands.addAtomSpecRange(map, Color.yellow, 2, 8, 8, "A");
- ChimeraCommands.addAtomSpecRange(map, Color.yellow, 2, 3, 5, "A");
- ChimeraCommands.addAtomSpecRange(map, Color.red, 1, 3, 5, "A");
- ChimeraCommands.addAtomSpecRange(map, Color.red, 1, 6, 9, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.blue, "1", 2, 5, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.blue, "1", 7, 7, "B");
+ ChimeraCommands.addAtomSpecRange(map, Color.blue, "1", 9, 23, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.blue, "2", 1, 1, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.blue, "2", 4, 7, "B");
+ ChimeraCommands.addAtomSpecRange(map, Color.yellow, "2", 8, 8, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.yellow, "2", 3, 5, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.red, "1", 3, 5, "A");
+ ChimeraCommands.addAtomSpecRange(map, Color.red, "1", 6, 9, "A");
- // Colours should appear in the Chimera command in the order in which
- // they were added; within colour, by model, by chain, ranges in start order
- String[] commands = new ChimeraXCommands().colourBySequence(map);
- assertEquals(commands.length, 1);
- assertEquals(
- commands[0],
- "color #1/A:2-5,9-23/B:7|#2/A:1/B:4-7 #0000ff; color #2/A:3-5,8 #ffff00; color #1/A:3-9 #ff0000");
+ /*
+ * Colours should appear in the Chimera command in the order in which
+ * they were added; within colour, by model, by chain, ranges in start order
+ */
+ List<StructureCommandI> commands = new ChimeraXCommands()
+ .colourBySequence(map);
+ assertEquals(commands.size(), 3);
+ assertEquals(commands.get(0).getCommand(),
+ "color #1/A:2-5,9-23/B:7|#2/A:1/B:4-7 #0000ff");
+ assertEquals(commands.get(1).getCommand(), "color #2/A:3-5,8 #ffff00");
+ assertEquals(commands.get(2).getCommand(), "color #1/A:3-9 #ff0000");
}
@Test(groups = { "Functional" })
* start with just one feature/value...
*/
featuresMap.put("chain", featureValues);
- ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 8, 20, "A");
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 8, 20, "A");
ChimeraXCommands commandGenerator = new ChimeraXCommands();
- String[] commands = commandGenerator.setAttributes(featuresMap);
- assertEquals(commands.length, 1);
+ List<StructureCommandI> commands = commandGenerator
+ .setAttributes(featuresMap);
+ assertEquals(commands.size(), 1);
/*
* feature name gets a jv_ namespace prefix
* feature value is quoted in case it contains spaces
*/
- assertEquals(commands[0],
+ assertEquals(commands.get(0).getCommand(),
"setattr #0/A:8-20 res jv_chain 'X' create true");
// add same feature value, overlapping range
- ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 3, 9, "A");
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 3, 9, "A");
// same feature value, contiguous range
- ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 21, 25, "A");
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 21, 25, "A");
commands = commandGenerator.setAttributes(featuresMap);
- assertEquals(commands.length, 1);
- assertEquals(commands[0],
+ assertEquals(commands.size(), 1);
+ assertEquals(commands.get(0).getCommand(),
"setattr #0/A:3-25 res jv_chain 'X' create true");
// same feature value and model, different chain
- ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 21, 25, "B");
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 21, 25, "B");
// same feature value and chain, different model
- ChimeraCommands.addAtomSpecRange(featureValues, "X", 1, 26, 30, "A");
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "1", 26, 30, "A");
commands = commandGenerator.setAttributes(featuresMap);
- assertEquals(commands.length, 1);
+ assertEquals(commands.size(), 1);
String expected1 = "setattr #0/A:3-25/B:21-25|#1/A:26-30 res jv_chain 'X' create true";
- assertEquals(commands[0], expected1);
+ assertEquals(commands.get(0).getCommand(), expected1);
// same feature, different value
- ChimeraCommands.addAtomSpecRange(featureValues, "Y", 0, 40, 50, "A");
+ ChimeraCommands.addAtomSpecRange(featureValues, "Y", "0", 40, 50, "A");
commands = commandGenerator.setAttributes(featuresMap);
- assertEquals(2, commands.length);
+ assertEquals(2, commands.size());
// commands are ordered by feature type but not by value
// so test for the expected command in either order
+ String cmd1 = commands.get(0).getCommand();
+ String cmd2 = commands.get(1).getCommand();
assertTrue(
- commands[0].equals(expected1) || commands[1].equals(expected1));
+ cmd1.equals(expected1) || cmd2.equals(expected1));
String expected2 = "setattr #0/A:40-50 res jv_chain 'Y' create true";
assertTrue(
- commands[0].equals(expected2) || commands[1].equals(expected2));
+ cmd1.equals(expected2) || cmd2.equals(expected2));
featuresMap.clear();
featureValues.clear();
featuresMap.put("side-chain binding!", featureValues);
ChimeraCommands.addAtomSpecRange(featureValues,
- "<html>metal <a href=\"http:a.b.c/x\"> 'ion!", 0, 7, 15,
+ "<html>metal <a href=\"http:a.b.c/x\"> 'ion!", "0", 7, 15,
"A");
// feature names are sanitised to change non-alphanumeric to underscore
// feature values are sanitised to encode single quote characters
commands = commandGenerator.setAttributes(featuresMap);
+ assertEquals(commands.size(), 1);
String expected3 = "setattr #0/A:7-15 res jv_side_chain_binding_ '<html>metal <a href=\"http:a.b.c/x\"> 'ion!' create true";
- assertTrue(
- commands[0].equals(expected3) || commands[1].equals(expected3));
+ assertTrue(commands.get(0).getCommand().equals(expected3));
}
@Test(groups = { "Functional" })
{
StructureCommandsI testee = new ChimeraXCommands();
AtomSpecModel ref = new AtomSpecModel();
- ref.addRange(1, 12, 14, "A");
- ref.addRange(1, 18, 18, "B");
- ref.addRange(1, 22, 23, "B");
+ ref.addRange("1", 12, 14, "A");
+ ref.addRange("1", 18, 18, "B");
+ ref.addRange("1", 22, 23, "B");
AtomSpecModel toAlign = new AtomSpecModel();
- toAlign.addRange(2, 15, 17, "B");
- toAlign.addRange(2, 20, 21, "B");
- toAlign.addRange(2, 22, 22, "C");
- String command = testee.superposeStructures(ref, toAlign);
+ toAlign.addRange("2", 15, 17, "B");
+ toAlign.addRange("2", 20, 21, "B");
+ toAlign.addRange("2", 22, 22, "C");
+ List<StructureCommandI> command = testee.superposeStructures(ref,
+ toAlign);
+ assertEquals(command.size(), 1);
+ String cmd = command.get(0).getCommand();
String refSpec = "#1/A:12-14/B:18,22-23";
String toAlignSpec = "#2/B:15-17,20-21/C:22";
String expected = String.format(
"align %s@CA|P toAtoms %s@CA|P; ribbon %s|%s; view",
refSpec, toAlignSpec, refSpec, toAlignSpec);
- assertEquals(command, expected);
+ assertEquals(cmd, expected);
}
@Test(groups = "Functional")
StructureCommandsI testee = new ChimeraXCommands();
AtomSpecModel model = new AtomSpecModel();
assertEquals(testee.getAtomSpec(model, false), "");
- model.addRange(1, 2, 4, "A");
+ model.addRange("1", 2, 4, "A");
assertEquals(testee.getAtomSpec(model, false), "#1/A:2-4");
- model.addRange(1, 8, 8, "A");
+ model.addRange("1", 8, 8, "A");
assertEquals(testee.getAtomSpec(model, false), "#1/A:2-4,8");
- model.addRange(1, 5, 7, "B");
+ model.addRange("1", 5, 7, "B");
assertEquals(testee.getAtomSpec(model, false), "#1/A:2-4,8/B:5-7");
- model.addRange(1, 3, 5, "A");
+ model.addRange("1", 3, 5, "A");
assertEquals(testee.getAtomSpec(model, false), "#1/A:2-5,8/B:5-7");
- model.addRange(0, 1, 4, "B");
+ model.addRange("0", 1, 4, "B");
assertEquals(testee.getAtomSpec(model, false),
"#0/B:1-4|#1/A:2-5,8/B:5-7");
- model.addRange(0, 5, 9, "C");
+ model.addRange("0", 5, 9, "C");
assertEquals(testee.getAtomSpec(model, false),
"#0/B:1-4/C:5-9|#1/A:2-5,8/B:5-7");
- model.addRange(1, 8, 10, "B");
+ model.addRange("1", 8, 10, "B");
assertEquals(testee.getAtomSpec(model, false),
"#0/B:1-4/C:5-9|#1/A:2-5,8/B:5-10");
- model.addRange(1, 8, 9, "B");
+ model.addRange("1", 8, 9, "B");
assertEquals(testee.getAtomSpec(model, false),
"#0/B:1-4/C:5-9|#1/A:2-5,8/B:5-10");
- model.addRange(0, 3, 10, "C"); // subsumes 5-9
+ model.addRange("0", 3, 10, "C"); // subsumes 5-9
assertEquals(testee.getAtomSpec(model, false),
"#0/B:1-4/C:3-10|#1/A:2-5,8/B:5-10");
- model.addRange(5, 25, 35, " ");
+ model.addRange("5", 25, 35, " ");
assertEquals(testee.getAtomSpec(model, false),
"#0/B:1-4/C:3-10|#1/A:2-5,8/B:5-10|#5/:25-35");
}
StructureCommandsI testee = new ChimeraXCommands();
AtomSpecModel model = new AtomSpecModel();
assertEquals(testee.getAtomSpec(model, true), "");
- model.addRange(1, 2, 4, "A");
+ model.addRange("1", 2, 4, "A");
assertEquals(testee.getAtomSpec(model, true), "#1/A:2-4@CA|P");
- model.addRange(1, 8, 8, "A");
+ model.addRange("1", 8, 8, "A");
assertEquals(testee.getAtomSpec(model, true), "#1/A:2-4,8@CA|P");
- model.addRange(1, 5, 7, "B");
+ model.addRange("1", 5, 7, "B");
assertEquals(testee.getAtomSpec(model, true), "#1/A:2-4,8/B:5-7@CA|P");
- model.addRange(1, 3, 5, "A");
+ model.addRange("1", 3, 5, "A");
assertEquals(testee.getAtomSpec(model, true), "#1/A:2-5,8/B:5-7@CA|P");
- model.addRange(0, 1, 4, "B");
+ model.addRange("0", 1, 4, "B");
assertEquals(testee.getAtomSpec(model, true),
"#0/B:1-4@CA|P|#1/A:2-5,8/B:5-7@CA|P");
- model.addRange(0, 5, 9, "C");
+ model.addRange("0", 5, 9, "C");
assertEquals(testee.getAtomSpec(model, true),
"#0/B:1-4/C:5-9@CA|P|#1/A:2-5,8/B:5-7@CA|P");
- model.addRange(1, 8, 10, "B");
+ model.addRange("1", 8, 10, "B");
assertEquals(testee.getAtomSpec(model, true),
"#0/B:1-4/C:5-9@CA|P|#1/A:2-5,8/B:5-10@CA|P");
- model.addRange(1, 8, 9, "B");
+ model.addRange("1", 8, 9, "B");
assertEquals(testee.getAtomSpec(model, true),
"#0/B:1-4/C:5-9@CA|P|#1/A:2-5,8/B:5-10@CA|P");
- model.addRange(0, 3, 10, "C"); // subsumes 5-9
+ model.addRange("0", 3, 10, "C"); // subsumes 5-9
assertEquals(testee.getAtomSpec(model, true),
"#0/B:1-4/C:3-10@CA|P|#1/A:2-5,8/B:5-10@CA|P");
- model.addRange(5, 25, 35, " "); // empty chain code
+ model.addRange("5", 25, 35, " "); // empty chain code
assertEquals(testee.getAtomSpec(model, true),
"#0/B:1-4/C:3-10@CA|P|#1/A:2-5,8/B:5-10@CA|P|#5/:25-35@CA|P");
}
public void testShowBackbone()
{
ChimeraCommands testee = new ChimeraXCommands();
- assertEquals(testee.showBackbone(), "~display all;show @CA|P pbonds");
+ List<StructureCommandI> showBackbone = testee.showBackbone();
+ assertEquals(showBackbone.size(), 1);
+ assertEquals(showBackbone.get(0).getCommand(),
+ "~display all;show @CA|P pbonds");
}
@Test(groups = "Functional")
public void testOpenCommandFile()
{
ChimeraCommands testee = new ChimeraXCommands();
- assertEquals(testee.openCommandFile("nowhere"), "open nowhere");
+ assertEquals(testee.openCommandFile("nowhere").getCommand(),
+ "open nowhere");
}
@Test(groups = "Functional")
public void testSaveSession()
{
ChimeraCommands testee = new ChimeraXCommands();
- assertEquals(testee.saveSession("somewhere"), "save session somewhere");
+ assertEquals(testee.saveSession("somewhere").getCommand(),
+ "save session somewhere");
}
@Test(groups = "Functional")
public void testGetColourCommand()
{
ChimeraCommands testee = new ChimeraXCommands();
- assertEquals(testee.getColourCommand("something", Color.MAGENTA),
+ assertEquals(testee.getColourCommand("something", Color.MAGENTA)
+ .getCommand(),
"color something #ff00ff");
}
{
ChimeraCommands testee = new ChimeraXCommands();
AtomSpecModel model = new AtomSpecModel();
- model.addRange(1, 89, 92, "A");
- model.addRange(2, 12, 20, "B");
- model.addRange(2, 8, 9, "B");
- assertEquals(testee.setAttribute("phi", "27.3", model),
+ model.addRange("1", 89, 92, "A");
+ model.addRange("2", 12, 20, "B");
+ model.addRange("2", 8, 9, "B");
+ assertEquals(testee.setAttribute("phi", "27.3", model).getCommand(),
"setattr #1/A:89-92|#2/B:8-9,12-20 res phi '27.3' create true");
}
}
import jalview.gui.StructureViewer.ViewerType;
import jalview.io.DataSourceType;
import jalview.io.FileLoader;
+import jalview.structure.StructureCommand;
import jalview.structure.StructureMapping;
import jalview.structure.StructureSelectionManager;
import jalview.ws.sifts.SiftsClient;
/*
* ask Chimera for its residue attribute names
*/
- List<String> reply = binding.executeCommand("list resattr", true);
+ List<String> reply = binding
+ .executeCommand(new StructureCommand("list resattr"), true);
// prefixed and sanitised attribute names for Jalview features:
assertTrue(reply.contains("resattr jv_domain"));
assertTrue(reply.contains("resattr jv_metal_ion_binding_site"));
* 91 and 96 on sequence --> residues 40 and 45 on chains A and B
*/
reply = binding.executeCommand(
- "list resi att jv_metal_ion_binding_site", true);
+ new StructureCommand("list resi att jv_metal_ion_binding_site"),
+ true);
assertEquals(reply.size(), 4);
assertTrue(reply
.contains("residue id #0:40.A jv_metal_ion_binding_site \"Iron-Sulfur (2Fe-2S)\" index 40"));
* check attributes with score values
* sequence positions 62 and 65 --> residues 11 and 14 on chains A and B
*/
- reply = binding.executeCommand("list resi att jv_kd", true);
+ reply = binding.executeCommand(
+ new StructureCommand("list resi att jv_kd"), true);
assertEquals(reply.size(), 4);
assertTrue(reply.contains("residue id #0:11.A jv_kd -2.1 index 11"));
assertTrue(reply.contains("residue id #0:14.A jv_kd 3.6 index 14"));
* list residues with positive kd score
*/
reply = binding.executeCommand(
- "list resi spec :*/jv_kd>0 attr jv_kd", true);
+ new StructureCommand("list resi spec :*/jv_kd>0 attr jv_kd"),
+ true);
assertEquals(reply.size(), 2);
assertTrue(reply.contains("residue id #0:14.A jv_kd 3.6 index 14"));
assertTrue(reply.contains("residue id #0:14.B jv_kd 3.6 index 14"));
{
AtomSpecModel model = new AtomSpecModel();
assertFalse(model.getModels().iterator().hasNext());
- List<int[]> ranges = model.getRanges(1, "A");
+ List<int[]> ranges = model.getRanges("1", "A");
assertTrue(ranges.isEmpty());
- model.addRange(1, 12, 14, "A");
- assertTrue(model.getRanges(1, "B").isEmpty());
- assertTrue(model.getRanges(2, "A").isEmpty());
- ranges = model.getRanges(1, "A");
+ model.addRange("1", 12, 14, "A");
+ assertTrue(model.getRanges("1", "B").isEmpty());
+ assertTrue(model.getRanges("2", "A").isEmpty());
+ ranges = model.getRanges("1", "A");
assertEquals(ranges.size(), 1);
int[] range = ranges.get(0);
assertEquals(range[0], 12);
* add some ranges; they should be coalesced and
* ordered when retrieved
*/
- model.addRange(1, 25, 25, "A");
- model.addRange(1, 20, 24, "A");
- model.addRange(1, 6, 8, "A");
- model.addRange(1, 13, 18, "A");
- model.addRange(1, 5, 6, "A");
- ranges = model.getRanges(1, "A");
+ model.addRange("1", 25, 25, "A");
+ model.addRange("1", 20, 24, "A");
+ model.addRange("1", 6, 8, "A");
+ model.addRange("1", 13, 18, "A");
+ model.addRange("1", 5, 6, "A");
+ ranges = model.getRanges("1", "A");
assertEquals(ranges.size(), 3);
range = ranges.get(0);
assertEquals(range[0], 5);
import jalview.schemes.JalviewColourScheme;
import jalview.structure.AtomSpec;
import jalview.structure.AtomSpecModel;
-import jalview.structure.StructureCommandsI.SuperposeData;
+import jalview.structure.StructureCommandI;
import jalview.structure.StructureMapping;
import jalview.structure.StructureSelectionManager;
}
@Override
- protected List<String> executeCommand(String command,
+ protected List<String> executeCommand(StructureCommandI command,
boolean getReply)
{
return null;
}
@Override
- protected int getModelNoForFile(String chainId)
+ protected String getModelIdForFile(String chainId)
{
- return 0;
+ return "";
}
@Override
}
@Override
- protected List<String> executeCommand(String command,
+ protected List<String> executeCommand(StructureCommandI command,
boolean getReply)
{
return null;
}
@Override
- protected int getModelNoForFile(String chainId)
+ protected String getModelIdForFile(String chainId)
{
- return 0;
+ return "";
}
@Override
/*
* create a data bean to hold data per structure file
*/
- SuperposeData[] structs = new SuperposeData[testee.getStructureFiles().length];
+ AAStructureBindingModel.SuperposeData[] structs = new AAStructureBindingModel.SuperposeData[testee.getStructureFiles().length];
for (int i = 0; i < structs.length; i++)
{
- structs[i] = new SuperposeData(al.getWidth(), 0);
+ structs[i] = new AAStructureBindingModel.SuperposeData(al.getWidth(), "0");
}
/*
* initialise BitSet of 'superposable columns' to true (would be false for
@Test(groups = { "Functional" })
public void testFindSuperposableResidues_hiddenColumn()
{
- SuperposeData[] structs = new SuperposeData[al.getHeight()];
+ AAStructureBindingModel.SuperposeData[] structs = new AAStructureBindingModel.SuperposeData[al.getHeight()];
for (int i = 0; i < structs.length; i++)
{
- structs[i] = new SuperposeData(al.getWidth(), 0);
+ structs[i] = new AAStructureBindingModel.SuperposeData(al.getWidth(), "0");
}
/*
* initialise BitSet of 'superposable columns' to true (would be false for