colourByCharge()
+ {
+ return Arrays.asList(COLOUR_BY_CHARGE);
+ }
+
+ @Override
+ public String getResidueSpec(String residue)
+ {
+ return ":" + residue;
+ }
+
+ @Override
+ public StructureCommandI colourResidues(String atomSpec, Color colour)
+ {
+ // https://www.cgl.ucsf.edu/chimerax/docs/user/commands/color.html
+ String colourCode = getColourString(colour);
+
+ return new StructureCommand("color " + atomSpec + " " + colourCode);
+ }
+
+ @Override
+ public StructureCommandI focusView()
+ {
+ return FOCUS_VIEW;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return
+ */
+ @Override
+ public int getModelStartNo()
+ {
+ return 1;
+ }
+
+ /**
+ * Returns a viewer command to set the given residue attribute value on
+ * residues specified by the AtomSpecModel, for example
+ *
+ *
+ * setattr #0/A:3-9,14-20,39-43 res jv_strand 'strand' create true
+ *
+ *
+ * @param attributeName
+ * @param attributeValue
+ * @param atomSpecModel
+ * @return
+ */
+ @Override
+ protected StructureCommandI setAttribute(String attributeName,
+ String attributeValue, AtomSpecModel atomSpecModel)
+ {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("setattr ")
+ .append(getAtomSpec(atomSpecModel, AtomSpecType.RESIDUE_ONLY));
+ sb.append(" res ").append(attributeName).append(" '")
+ .append(attributeValue).append("'");
+ sb.append(" create true");
+ return new StructureCommand(sb.toString());
+ }
+
+ @Override
+ public StructureCommandI openCommandFile(String path)
+ {
+ // https://www.cgl.ucsf.edu/chimerax/docs/user/commands/open.html
+ return new StructureCommand("open " + path);
+ }
+
+ @Override
+ public StructureCommandI saveSession(String filepath)
+ {
+ // https://www.cgl.ucsf.edu/chimerax/docs/user/commands/save.html
+ // note ChimeraX will append ".cxs" to the filepath!
+ return new StructureCommand("save " + filepath + " format session");
+ }
+
+ /**
+ * Returns the range(s) formatted as a ChimeraX atomspec, for example
+ *
+ * #1/A:2-20,30-40/B:10-20|#2/A:12-30
+ *
+ * Note there is no need to explicitly exclude ALTLOC atoms when
+ * {@code alphaOnly == true}, as this is the default behaviour of ChimeraX (a
+ * change from Chimera)
+ *
+ * @return
+ */
+ @Override
+ public String getAtomSpec(AtomSpecModel atomSpec, AtomSpecType specType)
+ {
+ StringBuilder sb = new StringBuilder(128);
+ boolean firstModel = true;
+ for (String model : atomSpec.getModels())
+ {
+ if (!firstModel)
+ {
+ sb.append("|");
+ }
+ firstModel = false;
+ appendModel(sb, model, atomSpec);
+ if (specType == AtomSpecType.ALPHA)
+ {
+ sb.append("@CA");
+ }
+ if (specType == AtomSpecType.PHOSPHATE)
+ {
+ sb.append("@P");
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * A helper method to append an atomSpec string for atoms in the given model
+ *
+ * @param sb
+ * @param model
+ * @param atomSpec
+ */
+ protected void appendModel(StringBuilder sb, String model,
+ AtomSpecModel atomSpec)
+ {
+ sb.append("#").append(model);
+
+ for (String chain : atomSpec.getChains(model))
+ {
+ boolean firstPositionForChain = true;
+ sb.append("/").append(chain.trim()).append(":");
+ List rangeList = atomSpec.getRanges(model, chain);
+ boolean first = true;
+ for (int[] range : rangeList)
+ {
+ if (!first)
+ {
+ sb.append(",");
+ }
+ first = false;
+ appendRange(sb, range[0], range[1], chain, firstPositionForChain,
+ true);
+ }
+ }
+ }
+
+ @Override
+ public List showBackbone()
+ {
+ return Arrays.asList(SHOW_BACKBONE);
+ }
+
+ @Override
+ public List superposeStructures(AtomSpecModel ref,
+ AtomSpecModel spec, AtomSpecType backbone)
+ {
+ /*
+ * Form ChimeraX match command to match spec to ref
+ *
+ * match #1/A:2-94 toAtoms #2/A:1-93
+ *
+ * @see https://www.cgl.ucsf.edu/chimerax/docs/user/commands/align.html
+ */
+ StringBuilder cmd = new StringBuilder();
+ String atomSpec = getAtomSpec(spec, backbone);
+ String refSpec = getAtomSpec(ref, backbone);
+ cmd.append("align ").append(atomSpec).append(" toAtoms ")
+ .append(refSpec);
+
+ /*
+ * show superposed residues as ribbon, others as chain
+ */
+ cmd.append("; ribbon ");
+ cmd.append(getAtomSpec(spec, AtomSpecType.RESIDUE_ONLY)).append("|");
+ cmd.append(getAtomSpec(ref, AtomSpecType.RESIDUE_ONLY))
+ .append("; view");
+
+ return Arrays.asList(new StructureCommand(cmd.toString()));
+ }
+
+ @Override
+ public StructureCommandI openSession(String filepath)
+ {
+ // https://www.cgl.ucsf.edu/chimerax/docs/user/commands/open.html#composite
+ // this version of the command has no dependency on file extension
+ return new StructureCommand("open " + filepath + " format session");
+ }
+
+ @Override
+ public StructureCommandI closeViewer()
+ {
+ return CLOSE_CHIMERAX;
+ }
+
+ @Override
+ public List startNotifications(String uri)
+ {
+ List cmds = new ArrayList<>();
+ cmds.add(new StructureCommand(
+ "info notify start models jalview prefix ModelChanged url "
+ + uri));
+ cmds.add(new StructureCommand(
+ "info notify start selection jalview prefix SelectionChanged url "
+ + uri));
+ return cmds;
+ }
+
+ @Override
+ public List stopNotifications()
+ {
+ List cmds = new ArrayList<>();
+ cmds.add(STOP_NOTIFY_MODELS);
+ cmds.add(STOP_NOTIFY_SELECTION);
+ return cmds;
+ }
+
+ @Override
+ public StructureCommandI getSelectedResidues()
+ {
+ return GET_SELECTION;
+ }
+
+ @Override
+ public StructureCommandI listResidueAttributes()
+ {
+ return LIST_RESIDUE_ATTRIBUTES;
+ }
+}