X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fext%2Frbvi%2Fchimera%2FChimeraXCommands.java;fp=src%2Fjalview%2Fext%2Frbvi%2Fchimera%2FChimeraXCommands.java;h=66ecaeafb653deb1c0dea064d959d217c9082686;hb=9949854f4c2dc75980f15acdee69594ca6b22631;hp=0000000000000000000000000000000000000000;hpb=cfba86992cd64bb0df6105bbf5dfc076ba8a93b2;p=jalview.git diff --git a/src/jalview/ext/rbvi/chimera/ChimeraXCommands.java b/src/jalview/ext/rbvi/chimera/ChimeraXCommands.java new file mode 100644 index 0000000..66ecaea --- /dev/null +++ b/src/jalview/ext/rbvi/chimera/ChimeraXCommands.java @@ -0,0 +1,294 @@ +/* + * 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 . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ +package jalview.ext.rbvi.chimera; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import jalview.structure.AtomSpecModel; +import jalview.structure.StructureCommand; +import jalview.structure.StructureCommandI; +import jalview.structure.StructureCommandsI.AtomSpecType; + +/** + * Routines for generating ChimeraX commands for Jalview/ChimeraX binding + */ +public class ChimeraXCommands extends ChimeraCommands +{ + // https://www.cgl.ucsf.edu/chimerax/docs/user/commands/info.html#resattr + private static final StructureCommand LIST_RESIDUE_ATTRIBUTES = new StructureCommand( + "info resattr"); + + // https://www.cgl.ucsf.edu/chimerax/docs/user/commands/exit.html + private static final StructureCommand CLOSE_CHIMERAX = new StructureCommand( + "exit"); + + // https://www.cgl.ucsf.edu/chimerax/docs/user/commands/info.html#notify + private static final StructureCommand STOP_NOTIFY_SELECTION = new StructureCommand( + "info notify stop selection jalview"); + + private static final StructureCommand STOP_NOTIFY_MODELS = new StructureCommand( + "info notify stop models jalview"); + + // https://www.cgl.ucsf.edu/chimerax/docs/user/commands/info.html#selection + private static final StructureCommand GET_SELECTION = new StructureCommand( + "info selection level residue"); + + private static final StructureCommand SHOW_BACKBONE = new StructureCommand( + "~display all;~ribbon;show @CA|P atoms"); + + // https://www.cgl.ucsf.edu/chimerax/docs/user/commands/view.html + 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 List 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; + } +}