import jalview.datamodel.SequenceI;
import jalview.gui.Desktop;
import jalview.renderer.seqfeatures.FeatureColourFinder;
+import jalview.structure.StructureCommandsBase;
import jalview.structure.StructureMapping;
import jalview.structure.StructureMappingcommandSet;
import jalview.structure.StructureSelectionManager;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
/**
* Routines for generating Chimera commands for Jalview/Chimera binding
* @author JimP
*
*/
-public class ChimeraCommands
+public class ChimeraCommands extends StructureCommandsBase
{
-
public static final String NAMESPACE_PREFIX = "jv_";
- /**
- * Constructs Chimera commands to colour residues as per the Jalview alignment
- *
- * @param ssm
- * @param files
- * @param sequence
- * @param sr
- * @param fr
- * @param viewPanel
- * @param isChimeraX
- * @return
- */
- public static StructureMappingcommandSet[] getColourBySequenceCommand(
+ protected static final String CMD_SEPARATOR = ";";
+
+ 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 String CMD_COLOUR_BY_CHAIN = "rainbow chain";
+
+ @Override
+ public String[] colourBySequence(
StructureSelectionManager ssm, String[] files,
SequenceI[][] sequence, SequenceRenderer sr,
- AlignmentViewPanel viewPanel, boolean isChimeraX)
+ AlignmentViewPanel viewPanel)
{
Map<Object, AtomSpecModel> colourMap = buildColoursMap(ssm, files,
- sequence, sr, viewPanel, isChimeraX);
-
- List<String> colourCommands = buildColourCommands(colourMap,
- isChimeraX);
+ sequence, sr, viewPanel);
- StructureMappingcommandSet cs = new StructureMappingcommandSet(
- ChimeraCommands.class, null,
- colourCommands.toArray(new String[colourCommands.size()]));
+ List<String> colourCommands = buildColourCommands(colourMap);
- return new StructureMappingcommandSet[] { cs };
+ return colourCommands.toArray(new String[colourCommands.size()]);
}
/**
* </pre>
*
* @param colourMap
- * @param isChimeraX
* @return
*/
- protected static List<String> buildColourCommands(
- Map<Object, AtomSpecModel> colourMap, boolean isChimeraX)
+ protected List<String> buildColourCommands(
+ Map<Object, AtomSpecModel> colourMap)
{
/*
* This version concatenates all commands into a single String (semi-colon
{
sb.append("; ");
}
- sb.append("color ");
firstColour = false;
final AtomSpecModel colourData = colourMap.get(colour);
- if (isChimeraX)
- {
- sb.append(colourData.getAtomSpecX()).append(" ").append(colourCode);
- }
- else
- {
- sb.append(colourCode).append(" ").append(colourData.getAtomSpec());
- }
+ sb.append(getColourCommand(colourData, colourCode));
}
commands.add(sb.toString());
return commands;
}
+ protected String getColourCommand(AtomSpecModel colourData,
+ String colourCode)
+ {
+ return "color " + colourCode + " " + colourData.getAtomSpec();
+ }
+
/**
* Traverses a map of { modelNumber, {chain, {list of from-to ranges} } } and
* builds a Chimera format atom spec
* @param sequence
* @param sr
* @param viewPanel
- * @param isChimeraX
* @return
*/
protected static Map<Object, AtomSpecModel> buildColoursMap(
StructureSelectionManager ssm, String[] files,
SequenceI[][] sequence, SequenceRenderer sr,
- AlignmentViewPanel viewPanel, boolean isChimeraX)
+ AlignmentViewPanel viewPanel)
{
FeatureRenderer fr = viewPanel.getFeatureRenderer();
FeatureColourFinder finder = new FeatureColourFinder(fr);
for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
- final int modelNumber = pdbfnum + (isChimeraX ? 1 : 0);
+ final int modelNumber = pdbfnum + getModelStartNo();
StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
if (mapping == null || mapping.length < 1)
return colourMap;
}
+ protected static int getModelStartNo()
+ {
+ return 0;
+ }
+
/**
* 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
*/
AtomSpecModel atomSpecModel = values.get(value);
StringBuilder sb = new StringBuilder(128);
- sb.append("setattr ");
+ sb.append("setattr");
if (isChimeraX)
{
- sb.append(atomSpecModel.getAtomSpecX());
+ sb.append(" ").append(atomSpecModel.getAtomSpecX());
}
String featureValue = value.toString();
featureValue = featureValue.replaceAll("\\'", "'");
return attName;
}
+ @Override
+ public String colourByChain()
+ {
+ return CMD_COLOUR_BY_CHAIN;
+ }
+
+ @Override
+ public String colourByCharge()
+ {
+ return CMD_COLOUR_BY_CHARGE;
+ }
+
+ @Override
+ public String colourByResidues(Map<String, Color> colours)
+ {
+ StringBuilder cmd = new StringBuilder(12 * colours.size());
+
+ /*
+ * concatenate commands like
+ * color #4949b6 ::VAL
+ */
+ for (Entry<String, Color> entry : colours.entrySet())
+ {
+ String colorSpec = ColorUtils.toTkCode(entry.getValue());
+ String resCode = entry.getKey();
+ cmd.append("color ").append(colorSpec).append(" ::").append(resCode)
+ .append(CMD_SEPARATOR);
+ }
+ return cmd.toString();
+ }
+
+ @Override
+ public String setBackgroundColour(Color col)
+ {
+ return "set bgColor " + ColorUtils.toTkCode(col);
+ }
+
+ @Override
+ public String focusView()
+ {
+ return "focus";
+ }
+
+ @Override
+ public String showChains(List<String> toShow)
+ {
+ /*
+ * Construct a chimera command like
+ *
+ * ~display #*;~ribbon #*;ribbon :.A,:.B
+ */
+ StringBuilder cmd = new StringBuilder(64);
+ boolean first = true;
+ for (String chain : toShow)
+ {
+ String[] tokens = chain.split(":");
+ if (tokens.length == 2)
+ {
+ String showChainCmd = tokens[0] + ":." + tokens[1];
+ if (!first)
+ {
+ cmd.append(",");
+ }
+ cmd.append(showChainCmd);
+ first = false;
+ }
+ }
+
+ /*
+ * could append ";focus" to this command to resize the display to fill the
+ * window, but it looks more helpful not to (easier to relate chains to the
+ * whole)
+ */
+ final String command = "~display #*; ~ribbon #*; ribbon :"
+ + cmd.toString();
+ return command;
+ }
+
}