status.loading_cached_pdb_entries = Loading Cached PDB Entries
status.searching_for_pdb_structures = Searching for PDB Structures
status.opening_file_for = opening file for
-status.colouring_chimera = Colouring Chimera
+status.colouring_structures = Colouring structures
label.font_doesnt_have_letters_defined = Font doesn't have letters defined\nso cannot be used\nwith alignment data
label.font_too_small = Font size is too small
label.error_loading_file_params = Error loading file {0}
tooltip.rnalifold_calculations=Se calcularán predicciones de estructura secondaria de RNA para el alineaminento, y se actualizarán si se efectuan cambios
tooltip.rnalifold_settings=Modificar la configuración de la predicción RNAAlifold. Úselo para ocultar o mostrar resultados del cálculo de RNA, o cambiar parámetros de el plegado de RNA.
label.show_selected_annotations=Mostrar anotaciones seleccionadas
-status.colouring_chimera=Coloreando Chimera
+status.colouring_structures=Coloreando estructuras
label.configure_displayed_columns=Configurar Columnas Mostradas
label.aacon_calculations=cálculos AACon
label.pdb_web-service_error=Error de servicio web PDB
import jalview.api.AlignmentViewPanel;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
-import jalview.schemes.ColourSchemeI;
import jalview.structures.models.AAStructureBindingModel;
public interface JalviewStructureDisplayI
void closeViewer(boolean closeExternalViewer);
/**
- * apply a colourscheme to the structures in the viewer
- *
- * @param colourScheme
- */
- void setJalviewColourScheme(ColourSchemeI colourScheme);
-
- /**
*
* @return true if all background sequence/structure binding threads have
* completed for this viewer instance
}
}
}
- jmb.centerViewer(toshow);
+ jmb.showChains(toshow);
}
void closeViewer()
else if (evt.getSource() == zappo)
{
setEnabled(zappo);
- jmb.setJalviewColourScheme(new ZappoColourScheme());
+ jmb.colourByJalviewColourScheme(new ZappoColourScheme());
}
else if (evt.getSource() == taylor)
{
setEnabled(taylor);
- jmb.setJalviewColourScheme(new TaylorColourScheme());
+ jmb.colourByJalviewColourScheme(new TaylorColourScheme());
}
else if (evt.getSource() == hydro)
{
setEnabled(hydro);
- jmb.setJalviewColourScheme(new HydrophobicColourScheme());
+ jmb.colourByJalviewColourScheme(new HydrophobicColourScheme());
}
else if (evt.getSource() == helix)
{
setEnabled(helix);
- jmb.setJalviewColourScheme(new HelixColourScheme());
+ jmb.colourByJalviewColourScheme(new HelixColourScheme());
}
else if (evt.getSource() == strand)
{
setEnabled(strand);
- jmb.setJalviewColourScheme(new StrandColourScheme());
+ jmb.colourByJalviewColourScheme(new StrandColourScheme());
}
else if (evt.getSource() == turn)
{
setEnabled(turn);
- jmb.setJalviewColourScheme(new TurnColourScheme());
+ jmb.colourByJalviewColourScheme(new TurnColourScheme());
}
else if (evt.getSource() == buried)
{
setEnabled(buried);
- jmb.setJalviewColourScheme(new BuriedColourScheme());
+ jmb.colourByJalviewColourScheme(new BuriedColourScheme());
}
else if (evt.getSource() == purinepyrimidine)
{
- jmb.setJalviewColourScheme(new PurinePyrimidineColourScheme());
+ jmb.colourByJalviewColourScheme(new PurinePyrimidineColourScheme());
}
else if (evt.getSource() == user)
{
*
* }
*/
- public void setJalviewColourScheme(UserColourScheme ucs)
+ public void colourByJalviewColourScheme(UserColourScheme ucs)
{
- jmb.setJalviewColourScheme(ucs);
+ jmb.colourByJalviewColourScheme(ucs);
}
public AlignmentPanel getAlignmentPanelFor(AlignmentI alignment)
}
else if (jmol != null)
{
- jmol.setJalviewColourScheme(ucs);
+ jmol.colourByJalviewColourScheme(ucs);
}
else if (pdbcanvas != null)
{
*/
package jalview.ext.jmol;
-import jalview.api.AlignmentViewPanel;
import jalview.api.FeatureRenderer;
-import jalview.api.SequenceRenderer;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.HiddenColumns;
import jalview.datamodel.PDBEntry;
import jalview.gui.IProgressIndicator;
import jalview.io.DataSourceType;
import jalview.io.StructureFile;
-import jalview.schemes.ColourSchemeI;
-import jalview.schemes.ResidueProperties;
import jalview.structure.AtomSpec;
-import jalview.structure.StructureMappingcommandSet;
import jalview.structure.StructureSelectionManager;
import jalview.structures.models.AAStructureBindingModel;
import jalview.util.MessageManager;
-import java.awt.Color;
import java.awt.Container;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.net.URL;
import java.util.ArrayList;
import java.util.BitSet;
-import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.jmol.api.JmolStatusListener;
import org.jmol.api.JmolViewer;
import org.jmol.c.CBK;
-import org.jmol.script.T;
import org.jmol.viewer.Viewer;
public abstract class JalviewJmolBinding extends AAStructureBindingModel
Vector<String> atomsPicked = new Vector<>();
- private List<String> chainNames;
-
- Hashtable<String, String> chainFile;
-
/*
* the default or current model displayed if the model cannot be identified
* from the selection message
DataSourceType protocol)
{
super(ssm, pdbentry, sequenceIs, protocol);
+ setStructureCommands(new JmolCommands());
/*
* viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
* "jalviewJmol", ap.av.applet .getDocumentBase(),
jmolViewer = theViewer;
jmolViewer.setJmolStatusListener(this);
jmolViewer.addSelectionListener(this);
+ setStructureCommands(new JmolCommands());
}
/**
return getViewerTitle("Jmol", true);
}
- /**
- * prepare the view for a given set of models/chains. chainList contains
- * strings of the form 'pdbfilename:Chaincode'
- *
- * @param chainList
- * list of chains to make visible
- */
- public void centerViewer(Vector<String> chainList)
- {
- StringBuilder cmd = new StringBuilder(128);
- int mlength, p;
- for (String lbl : chainList)
- {
- mlength = 0;
- do
- {
- p = mlength;
- mlength = lbl.indexOf(":", p);
- } while (p < mlength && mlength < (lbl.length() - 2));
- // TODO: lookup each pdb id and recover proper model number for it.
- cmd.append(":" + lbl.substring(mlength + 1) + " /"
- + (1 + getModelNum(chainFile.get(lbl))) + " or ");
- }
- if (cmd.length() > 0)
- {
- cmd.setLength(cmd.length() - 4);
- }
- evalStateCommand("select *;restrict " + cmd + ";cartoon;center " + cmd);
- }
-
public void closeViewer()
{
// remove listeners for all structures in viewer
releaseUIResources();
}
- @Override
- public void colourByChain()
- {
- colourBySequence = false;
- // TODO: colour by chain should colour each chain distinctly across all
- // visible models
- // TODO: http://issues.jalview.org/browse/JAL-628
- evalStateCommand("select *;color chain");
- }
-
- @Override
- public void colourByCharge()
- {
- colourBySequence = false;
- evalStateCommand("select *;color white;select ASP,GLU;color red;"
- + "select LYS,ARG;color blue;select CYS;color yellow");
- }
-
/**
* superpose the structures associated with sequences in the alignment
* according to their corresponding positions.
{
// TODO is performing selectioncom redundant here? is done later on
// System.out.println("Select regions:\n" + selectioncom.toString());
- evalStateCommand("select *; cartoons off; backbone; select ("
- + selectioncom.toString() + "); cartoons; ");
+ executeCommand("select *; cartoons off; backbone; select ("
+ + selectioncom.toString() + "); cartoons; ", false);
// selcom.append("; ribbons; ");
String cmdString = command.toString();
// System.out.println("Superimpose command(s):\n" + cmdString);
- evalStateCommand(cmdString);
+ executeCommand(cmdString, false);
}
}
if (selectioncom.length() > 0)
selectioncom.setLength(selectioncom.length() - 1);
}
// System.out.println("Select regions:\n" + selectioncom.toString());
- evalStateCommand("select *; cartoons off; backbone; select ("
- + selectioncom.toString() + "); cartoons; ");
+ executeCommand("select *; cartoons off; backbone; select ("
+ + selectioncom.toString() + "); cartoons; ", false);
// evalStateCommand("select *; backbone; select "+selcom.toString()+";
// cartoons; center "+selcom.toString());
}
return null;
}
- public void evalStateCommand(String command)
+ @Override
+ public List<String> executeCommand(String command, boolean getReply)
{
+ if (command == null)
+ {
+ return null;
+ }
jmolHistory(false);
if (lastCommand == null || !lastCommand.equals(command))
{
}
jmolHistory(true);
lastCommand = command;
- }
-
- Thread colourby = null;
- /**
- * Sends a set of colour commands to the structure viewer
- *
- * @param colourBySequenceCommands
- */
- @Override
- protected void colourBySequence(
- final StructureMappingcommandSet[] colourBySequenceCommands)
- {
- if (colourby != null)
- {
- colourby.interrupt();
- colourby = null;
- }
- colourby = new Thread(new Runnable()
- {
- @Override
- public void run()
- {
- for (StructureMappingcommandSet cpdbbyseq : colourBySequenceCommands)
- {
- for (String cbyseq : cpdbbyseq.commands)
- {
- executeWhenReady(cbyseq);
- }
- }
- }
- });
- colourby.start();
- }
-
- /**
- * @param files
- * @param sr
- * @param viewPanel
- * @return
- */
- @Override
- protected StructureMappingcommandSet[] getColourBySequenceCommands(
- String[] files, SequenceRenderer sr, AlignmentViewPanel viewPanel)
- {
- return JmolCommands.getColourBySequenceCommand(getSsm(), files,
- getSequence(), sr, viewPanel);
- }
-
- /**
- * @param command
- */
- protected void executeWhenReady(String command)
- {
- evalStateCommand(command);
+ return null;
}
public void createImage(String file, String type, int quality)
return null;
}
- public Color getColour(int atomIndex, int pdbResNum, String chain,
- String pdbfile)
- {
- if (getModelNum(pdbfile) < 0)
- {
- return null;
- }
- // TODO: verify atomIndex is selecting correct model.
- // return new Color(viewer.getAtomArgb(atomIndex)); Jmol 12.2.4
- int colour = jmolViewer.ms.at[atomIndex].atomPropertyInt(T.color);
- return new Color(colour);
- }
-
/**
* instruct the Jalview binding to update the pdbentries vector if necessary
* prior to matching the jmol view's contents to the list of structure files
*/
public abstract void refreshPdbEntries();
- private int getModelNum(String modelFileName)
- {
- String[] mfn = getStructureFiles();
- if (mfn == null)
- {
- return -1;
- }
- for (int i = 0; i < mfn.length; i++)
- {
- if (mfn[i].equalsIgnoreCase(modelFileName))
- {
- return i;
- }
- }
- return -1;
- }
-
/**
* map between index of model filename returned from getPdbFile and the first
* index of models from this file in the viewer. Note - this is not trimmed -
sb.append(";set hoverLabel \"").append(toks.nextToken()).append(" ")
.append(toks.nextToken());
sb.append("|").append(label).append("\"");
- evalStateCommand(sb.toString());
+ executeCommand(sb.toString(), false);
}
}
fileLoadingError = null;
String[] oldmodels = modelFileNames;
modelFileNames = null;
- chainNames = new ArrayList<>();
- chainFile = new Hashtable<>();
boolean notifyLoaded = false;
String[] modelfilenames = getStructureFiles();
// first check if we've lost any structures
// add an entry for every chain in the model
for (int i = 0; i < pdb.getChains().size(); i++)
{
- String chid = new String(
- pdb.getId() + ":" + pdb.getChains().elementAt(i).id);
- chainFile.put(chid, fileName);
- chainNames.add(chid);
+ String chid = pdb.getId() + ":"
+ + pdb.getChains().elementAt(i).id;
+ addChainFile(chid, fileName);
+ getChainNames().add(chid);
}
notifyLoaded = true;
}
setLoadingFromArchive(false);
}
- @Override
- public List<String> getChainNames()
- {
- return chainNames;
- }
-
protected IProgressIndicator getIProgressIndicator()
{
return null;
}
- @Override
- public void setJalviewColourScheme(ColourSchemeI cs)
- {
- colourBySequence = false;
-
- if (cs == null)
- {
- return;
- }
-
- jmolHistory(false);
- StringBuilder command = new StringBuilder(128);
- command.append("select *;color white;");
- List<String> residueSet = ResidueProperties.getResidues(isNucleotide(),
- false);
- for (String resName : residueSet)
- {
- char res = resName.length() == 3
- ? ResidueProperties.getSingleCharacterCode(resName)
- : resName.charAt(0);
- Color col = cs.findColour(res, 0, null, null, 0f);
- command.append("select " + resName + ";color[" + col.getRed() + ","
- + col.getGreen() + "," + col.getBlue() + "];");
- }
-
- evalStateCommand(command.toString());
- jmolHistory(true);
- }
-
public void showHelp()
{
showUrl("http://jmol.sourceforge.net/docs/JmolUserGuide/", "jmolHelp");
protected org.jmol.api.JmolAppConsoleInterface console = null;
@Override
- public void setBackgroundColour(java.awt.Color col)
- {
- jmolHistory(false);
- jmolViewer.evalStringQuiet("background [" + col.getRed() + ","
- + col.getGreen() + "," + col.getBlue() + "];");
- jmolHistory(true);
- }
-
- @Override
public int[] resizeInnerPanel(String data)
{
// Jalview doesn't honour resize panel requests
{
showConsole(false);
}
+
+ @Override
+ protected int getModelNoForFile(String pdbFile)
+ {
+ if (modelFileNames == null)
+ {
+ return -1;
+ }
+ for (int i = 0; i < modelFileNames.length; i++)
+ {
+ if (modelFileNames[i].equalsIgnoreCase(pdbFile))
+ {
+ return i;
+ }
+ }
+ return -1;
+
+ }
}
import jalview.datamodel.HiddenColumns;
import jalview.datamodel.SequenceI;
import jalview.renderer.seqfeatures.FeatureColourFinder;
+import jalview.structure.StructureCommandsBase;
import jalview.structure.StructureMapping;
-import jalview.structure.StructureMappingcommandSet;
import jalview.structure.StructureSelectionManager;
+import jalview.util.Comparison;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
/**
- * Routines for generating Jmol commands for Jalview/Jmol binding another
- * cruisecontrol test.
+ * Routines for generating Jmol commands for Jalview/Jmol binding
*
* @author JimP
*
*/
-public class JmolCommands
+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";
- /**
- * Jmol utility which constructs the commands to colour chains by the given
- * alignment
- *
- * @returns Object[] { Object[] { <model being coloured>,
- *
- */
- public static StructureMappingcommandSet[] getColourBySequenceCommand(
+ private static final String CMD_COLOUR_BY_CHAIN = "select *;color chain";
+
+ private static String formatRGB(Color c) {
+ return c == null ? null
+ : String.format("[%d,%d,%d]", c.getRed(), c.getGreen(),
+ c.getBlue());
+ }
+
+ @Override
+ public String[] colourBySequence(
StructureSelectionManager ssm, String[] files,
SequenceI[][] sequence, SequenceRenderer sr,
AlignmentViewPanel viewPanel)
{
+ // TODO refactor to call buildColoursMap() first...
+
FeatureRenderer fr = viewPanel.getFeatureRenderer();
FeatureColourFinder finder = new FeatureColourFinder(fr);
AlignViewportI viewport = viewPanel.getAlignViewport();
HiddenColumns cs = viewport.getAlignment().getHiddenColumns();
AlignmentI al = viewport.getAlignment();
- List<StructureMappingcommandSet> cset = new ArrayList<StructureMappingcommandSet>();
+ List<String> cset = new ArrayList<>();
for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
- StringBuffer command = new StringBuffer();
- StructureMappingcommandSet smc;
- ArrayList<String> str = new ArrayList<String>();
+ StringBuilder command = new StringBuilder(128);
+ List<String> str = new ArrayList<>();
if (mapping == null || mapping.length < 1)
{
for (int r = 0; r < asp.getLength(); r++)
{
// no mapping to gaps in sequence
- if (jalview.util.Comparison.isGap(asp.getCharAt(r)))
+ if (Comparison.isGap(asp.getCharAt(r)))
{
continue;
}
str.add(command.toString());
command.setLength(0);
}
- // Finally, add the command set ready to be returned.
- cset.add(new StructureMappingcommandSet(JmolCommands.class,
- files[pdbfnum], str.toArray(new String[str.size()])));
+ cset.addAll(str);
}
- return cset.toArray(new StructureMappingcommandSet[cset.size()]);
+ return cset.toArray(new String[cset.size()]);
}
- public static StringBuffer condenseCommand(StringBuffer command, int pos)
+ public static StringBuilder condenseCommand(StringBuilder command,
+ int pos)
{
// work back to last 'select'
;
} while ((q = command.indexOf("select", p)) == -1 && p > 0);
- StringBuffer sb = new StringBuffer(command.substring(0, q + 7));
+ StringBuilder sb = new StringBuilder(command.substring(0, q + 7));
command = command.delete(0, q + 7);
return sb;
}
+ @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(128);
+ cmd.append("select *;color white;");
+
+ /*
+ * concatenate commands like
+ * select VAL;color[100,215,55]
+ */
+ for (Entry<String, Color> entry : colours.entrySet())
+ {
+ Color col = entry.getValue();
+ String resCode = entry.getKey();
+ cmd.append("select ").append(resCode).append(";");
+ cmd.append("color[");
+ cmd.append(formatRGB(col));
+ cmd.append("];");
+ }
+
+ return cmd.toString();
+ }
+
+ @Override
+ public String setBackgroundColour(Color col)
+ {
+ return "background " + formatRGB(col);
+ }
+
+ @Override
+ public String focusView()
+ {
+ return "zoom 0";
+ }
+
+ @Override
+ public String showChains(List<String> toShow)
+ {
+ StringBuilder atomSpec = new StringBuilder(128);
+ boolean first = true;
+ for (String chain : toShow)
+ {
+ String[] tokens = chain.split(":");
+ if (tokens.length == 2)
+ {
+ if (!first)
+ {
+ atomSpec.append(" or ");
+ }
+ first = false;
+ atomSpec.append(":").append(tokens[1]).append(" /").append(tokens[0]);
+ }
+ }
+
+ String spec = atomSpec.toString();
+ String command = "select *;restrict " + spec + ";cartoon;center "
+ + spec;
+ return command;
+ }
+
}
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;
+ }
+
}
--- /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.rbvi.chimera;
+
+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.MappedFeatures;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.gui.Desktop;
+import jalview.renderer.seqfeatures.FeatureColourFinder;
+import jalview.structure.StructureMapping;
+import jalview.structure.StructureMappingcommandSet;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.ColorUtils;
+import jalview.util.Comparison;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Routines for generating ChimeraX commands for Jalview/ChimeraX binding
+ */
+public class ChimeraXCommands extends ChimeraCommands
+{
+ public static final String NAMESPACE_PREFIX = "jv_";
+
+ private static final String CMD_COLOUR_BY_CHARGE = "color white;color :ASP,GLU red;color :LYS,ARG blue;color :CYS yellow";
+
+ /**
+ * Traverses a map of { modelNumber, {chain, {list of from-to ranges} } } and
+ * builds a Chimera format atom spec
+ *
+ * @param modelAndChainRanges
+ */
+ protected static String getAtomSpec(
+ Map<Integer, Map<String, List<int[]>>> modelAndChainRanges)
+ {
+ StringBuilder sb = new StringBuilder(128);
+ boolean firstModelForColour = true;
+ for (Integer model : modelAndChainRanges.keySet())
+ {
+ boolean firstPositionForModel = true;
+ if (!firstModelForColour)
+ {
+ sb.append("|");
+ }
+ firstModelForColour = false;
+ sb.append("#").append(model).append(":");
+
+ final Map<String, List<int[]>> modelData = modelAndChainRanges
+ .get(model);
+ for (String chain : modelData.keySet())
+ {
+ boolean hasChain = !"".equals(chain.trim());
+ for (int[] range : modelData.get(chain))
+ {
+ if (!firstPositionForModel)
+ {
+ sb.append(",");
+ }
+ if (range[0] == range[1])
+ {
+ sb.append(range[0]);
+ }
+ else
+ {
+ sb.append(range[0]).append("-").append(range[1]);
+ }
+ if (hasChain)
+ {
+ sb.append(".").append(chain);
+ }
+ firstPositionForModel = false;
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * <pre>
+ * Build a data structure which records contiguous subsequences for each colour.
+ * From this we can easily generate the Chimera command for colour by sequence.
+ * Color
+ * Model number
+ * Chain
+ * list of start/end ranges
+ * Ordering is by order of addition (for colours and positions), natural ordering (for models and chains)
+ * </pre>
+ */
+ protected static Map<Object, AtomSpecModel> buildColoursMap(
+ StructureSelectionManager ssm, String[] files,
+ SequenceI[][] sequence, SequenceRenderer sr,
+ AlignmentViewPanel viewPanel)
+ {
+ FeatureRenderer fr = viewPanel.getFeatureRenderer();
+ FeatureColourFinder finder = new FeatureColourFinder(fr);
+ AlignViewportI viewport = viewPanel.getAlignViewport();
+ HiddenColumns cs = viewport.getAlignment().getHiddenColumns();
+ AlignmentI al = viewport.getAlignment();
+ Map<Object, AtomSpecModel> colourMap = new LinkedHashMap<>();
+ Color lastColour = null;
+
+ for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
+ {
+ StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
+
+ if (mapping == null || mapping.length < 1)
+ {
+ continue;
+ }
+
+ int startPos = -1, lastPos = -1;
+ String lastChain = "";
+ for (int s = 0; s < sequence[pdbfnum].length; s++)
+ {
+ for (int sp, m = 0; m < mapping.length; m++)
+ {
+ final SequenceI seq = sequence[pdbfnum][s];
+ if (mapping[m].getSequence() == seq
+ && (sp = al.findIndex(seq)) > -1)
+ {
+ SequenceI asp = al.getSequenceAt(sp);
+ for (int r = 0; r < asp.getLength(); r++)
+ {
+ // no mapping to gaps in sequence
+ if (Comparison.isGap(asp.getCharAt(r)))
+ {
+ continue;
+ }
+ int pos = mapping[m].getPDBResNum(asp.findPosition(r));
+
+ if (pos < 1 || pos == lastPos)
+ {
+ continue;
+ }
+
+ Color colour = sr.getResidueColour(seq, r, finder);
+
+ /*
+ * darker colour for hidden regions
+ */
+ if (!cs.isVisible(r))
+ {
+ colour = Color.GRAY;
+ }
+
+ final String chain = mapping[m].getChain();
+
+ /*
+ * Just keep incrementing the end position for this colour range
+ * _unless_ colour, PDB model or chain has changed, or there is a
+ * gap in the mapped residue sequence
+ */
+ final boolean newColour = !colour.equals(lastColour);
+ final boolean nonContig = lastPos + 1 != pos;
+ final boolean newChain = !chain.equals(lastChain);
+ if (newColour || nonContig || newChain)
+ {
+ if (startPos != -1)
+ {
+ addAtomSpecRange(colourMap, lastColour, pdbfnum, startPos,
+ lastPos, lastChain);
+ }
+ startPos = pos;
+ }
+ lastColour = colour;
+ lastPos = pos;
+ lastChain = chain;
+ }
+ // final colour range
+ if (lastColour != null)
+ {
+ addAtomSpecRange(colourMap, lastColour, pdbfnum, startPos,
+ lastPos, lastChain);
+ }
+ // break;
+ }
+ }
+ }
+ }
+ return colourMap;
+ }
+
+ /**
+ * 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>
+ * <li>a colour, when building a 'colour structure by sequence' command</li>
+ * <li>a feature value, when building a 'set Chimera attributes from features'
+ * command</li>
+ * </ul>
+ *
+ * @param map
+ * @param value
+ * @param model
+ * @param startPos
+ * @param endPos
+ * @param chain
+ */
+ protected static void addAtomSpecRange(Map<Object, AtomSpecModel> map,
+ Object value, int model, int startPos, int endPos, String chain)
+ {
+ /*
+ * Get/initialize map of data for the colour
+ */
+ AtomSpecModel atomSpec = map.get(value);
+ if (atomSpec == null)
+ {
+ atomSpec = new AtomSpecModel();
+ map.put(value, atomSpec);
+ }
+
+ atomSpec.addRange(model, startPos, endPos, chain);
+ }
+
+ /**
+ * Constructs and returns Chimera commands to set attributes on residues
+ * corresponding to features in Jalview. Attribute names are the Jalview
+ * feature type, with a "jv_" prefix.
+ *
+ * @param ssm
+ * @param files
+ * @param seqs
+ * @param viewPanel
+ * @return
+ */
+ public static StructureMappingcommandSet getSetAttributeCommandsForFeatures(
+ StructureSelectionManager ssm, String[] files, SequenceI[][] seqs,
+ AlignmentViewPanel viewPanel)
+ {
+ Map<String, Map<Object, AtomSpecModel>> featureMap = buildFeaturesMap(
+ ssm, files, seqs, viewPanel);
+
+ List<String> commands = buildSetAttributeCommands(featureMap);
+
+ StructureMappingcommandSet cs = new StructureMappingcommandSet(
+ ChimeraXCommands.class, null,
+ commands.toArray(new String[commands.size()]));
+
+ return cs;
+ }
+
+ /**
+ * <pre>
+ * Helper method to build a map of
+ * { featureType, { feature value, AtomSpecModel } }
+ * </pre>
+ *
+ * @param ssm
+ * @param files
+ * @param seqs
+ * @param viewPanel
+ * @return
+ */
+ protected static Map<String, Map<Object, AtomSpecModel>> buildFeaturesMap(
+ StructureSelectionManager ssm, String[] files, SequenceI[][] seqs,
+ AlignmentViewPanel viewPanel)
+ {
+ Map<String, Map<Object, AtomSpecModel>> theMap = new LinkedHashMap<>();
+
+ FeatureRenderer fr = viewPanel.getFeatureRenderer();
+ if (fr == null)
+ {
+ return theMap;
+ }
+
+ AlignViewportI viewport = viewPanel.getAlignViewport();
+ List<String> visibleFeatures = fr.getDisplayedFeatureTypes();
+
+ /*
+ * if alignment is showing features from complement, we also transfer
+ * these features to the corresponding mapped structure residues
+ */
+ boolean showLinkedFeatures = viewport.isShowComplementFeatures();
+ List<String> complementFeatures = new ArrayList<>();
+ FeatureRenderer complementRenderer = null;
+ if (showLinkedFeatures)
+ {
+ AlignViewportI comp = fr.getViewport().getCodingComplement();
+ if (comp != null)
+ {
+ complementRenderer = Desktop.getAlignFrameFor(comp)
+ .getFeatureRenderer();
+ complementFeatures = complementRenderer.getDisplayedFeatureTypes();
+ }
+ }
+ if (visibleFeatures.isEmpty() && complementFeatures.isEmpty())
+ {
+ return theMap;
+ }
+
+ AlignmentI alignment = viewPanel.getAlignment();
+ for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
+ {
+ StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
+
+ if (mapping == null || mapping.length < 1)
+ {
+ continue;
+ }
+
+ for (int seqNo = 0; seqNo < seqs[pdbfnum].length; seqNo++)
+ {
+ for (int m = 0; m < mapping.length; m++)
+ {
+ final SequenceI seq = seqs[pdbfnum][seqNo];
+ int sp = alignment.findIndex(seq);
+ StructureMapping structureMapping = mapping[m];
+ if (structureMapping.getSequence() == seq && sp > -1)
+ {
+ /*
+ * found a sequence with a mapping to a structure;
+ * now scan its features
+ */
+ if (!visibleFeatures.isEmpty())
+ {
+ scanSequenceFeatures(visibleFeatures, structureMapping, seq,
+ theMap, pdbfnum);
+ }
+ if (showLinkedFeatures)
+ {
+ scanComplementFeatures(complementRenderer, structureMapping,
+ seq, theMap, pdbfnum);
+ }
+ }
+ }
+ }
+ }
+ return theMap;
+ }
+
+ /**
+ * Scans visible features in mapped positions of the CDS/peptide complement, and
+ * adds any found to the map of attribute values/structure positions
+ *
+ * @param complementRenderer
+ * @param structureMapping
+ * @param seq
+ * @param theMap
+ * @param modelNumber
+ */
+ protected static void scanComplementFeatures(
+ FeatureRenderer complementRenderer,
+ StructureMapping structureMapping, SequenceI seq,
+ Map<String, Map<Object, AtomSpecModel>> theMap, int modelNumber)
+ {
+ /*
+ * for each sequence residue mapped to a structure position...
+ */
+ for (int seqPos : structureMapping.getMapping().keySet())
+ {
+ /*
+ * find visible complementary features at mapped position(s)
+ */
+ MappedFeatures mf = complementRenderer
+ .findComplementFeaturesAtResidue(seq, seqPos);
+ if (mf != null)
+ {
+ for (SequenceFeature sf : mf.features)
+ {
+ String type = sf.getType();
+
+ /*
+ * Don't copy features which originated from Chimera
+ */
+ if (JalviewChimeraBinding.CHIMERA_FEATURE_GROUP
+ .equals(sf.getFeatureGroup()))
+ {
+ continue;
+ }
+
+ /*
+ * record feature 'value' (score/description/type) as at the
+ * corresponding structure position
+ */
+ List<int[]> mappedRanges = structureMapping
+ .getPDBResNumRanges(seqPos, seqPos);
+
+ if (!mappedRanges.isEmpty())
+ {
+ String value = sf.getDescription();
+ if (value == null || value.length() == 0)
+ {
+ value = type;
+ }
+ float score = sf.getScore();
+ if (score != 0f && !Float.isNaN(score))
+ {
+ value = Float.toString(score);
+ }
+ Map<Object, AtomSpecModel> featureValues = theMap.get(type);
+ if (featureValues == null)
+ {
+ featureValues = new HashMap<>();
+ theMap.put(type, featureValues);
+ }
+ for (int[] range : mappedRanges)
+ {
+ addAtomSpecRange(featureValues, value, modelNumber, range[0],
+ range[1], structureMapping.getChain());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 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
+ */
+ protected static void scanSequenceFeatures(List<String> visibleFeatures,
+ StructureMapping mapping, SequenceI seq,
+ Map<String, Map<Object, AtomSpecModel>> theMap, int modelNumber)
+ {
+ List<SequenceFeature> sfs = seq.getFeatures().getPositionalFeatures(
+ visibleFeatures.toArray(new String[visibleFeatures.size()]));
+ for (SequenceFeature sf : sfs)
+ {
+ String type = sf.getType();
+
+ /*
+ * Don't copy features which originated from Chimera
+ */
+ if (JalviewChimeraBinding.CHIMERA_FEATURE_GROUP
+ .equals(sf.getFeatureGroup()))
+ {
+ continue;
+ }
+
+ List<int[]> mappedRanges = mapping.getPDBResNumRanges(sf.getBegin(),
+ sf.getEnd());
+
+ if (!mappedRanges.isEmpty())
+ {
+ String value = sf.getDescription();
+ if (value == null || value.length() == 0)
+ {
+ value = type;
+ }
+ float score = sf.getScore();
+ if (score != 0f && !Float.isNaN(score))
+ {
+ value = Float.toString(score);
+ }
+ Map<Object, AtomSpecModel> featureValues = theMap.get(type);
+ if (featureValues == null)
+ {
+ featureValues = new HashMap<>();
+ theMap.put(type, featureValues);
+ }
+ for (int[] range : mappedRanges)
+ {
+ addAtomSpecRange(featureValues, value, modelNumber, range[0],
+ range[1], mapping.getChain());
+ }
+ }
+ }
+ }
+
+ /**
+ * Traverse the map of features/values/models/chains/positions to construct a
+ * list of 'setattr' commands (one per distinct feature type and value).
+ * <p>
+ * The format of each command is
+ *
+ * <pre>
+ * <blockquote> setattr r <featureName> " " #modelnumber:range.chain
+ * e.g. setattr r jv:chain <value> #0:2.B,4.B,9-12.B|#1:1.A,2-6.A,...
+ * </blockquote>
+ * </pre>
+ *
+ * @param featureMap
+ * @return
+ */
+ protected static List<String> buildSetAttributeCommands(
+ Map<String, Map<Object, AtomSpecModel>> featureMap)
+ {
+ List<String> commands = new ArrayList<>();
+ for (String featureType : featureMap.keySet())
+ {
+ String attributeName = makeAttributeName(featureType);
+
+ /*
+ * clear down existing attributes for this feature
+ */
+ // 'problem' - sets attribute to None on all residues - overkill?
+ // commands.add("~setattr r " + attributeName + " :*");
+
+ Map<Object, AtomSpecModel> values = featureMap.get(featureType);
+ for (Object value : values.keySet())
+ {
+ /*
+ * for each distinct value recorded for this feature type,
+ * add a command to set the attribute on the mapped residues
+ * Put values in single quotes, encoding any embedded single quotes
+ */
+ StringBuilder sb = new StringBuilder(128);
+ String featureValue = value.toString();
+ featureValue = featureValue.replaceAll("\\'", "'");
+ sb.append("setattr r ").append(attributeName).append(" '")
+ .append(featureValue).append("' ");
+ sb.append(values.get(value).getAtomSpec());
+ commands.add(sb.toString());
+ }
+ }
+
+ return commands;
+ }
+
+ /**
+ * Makes a prefixed and valid Chimera attribute name. A jv_ prefix is applied
+ * for a 'Jalview' namespace, and any non-alphanumeric character is converted
+ * to an underscore.
+ *
+ * @param featureType
+ * @return
+ *
+ * <pre>
+ * @see https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/setattr.html
+ * </pre>
+ */
+ protected static String makeAttributeName(String featureType)
+ {
+ StringBuilder sb = new StringBuilder();
+ if (featureType != null)
+ {
+ for (char c : featureType.toCharArray())
+ {
+ sb.append(Character.isLetterOrDigit(c) ? c : '_');
+ }
+ }
+ String attName = NAMESPACE_PREFIX + sb.toString();
+
+ /*
+ * Chimera treats an attribute name ending in 'color' as colour-valued;
+ * Jalview doesn't, so prevent this by appending an underscore
+ */
+ if (attName.toUpperCase().endsWith("COLOR"))
+ {
+ attName += "_";
+ }
+
+ return attName;
+ }
+
+ @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 :VAL #4949b6
+ */
+ for (Entry<String, Color> entry : colours.entrySet())
+ {
+ String colorSpec = ColorUtils.toTkCode(entry.getValue());
+ String resCode = entry.getKey();
+ cmd.append("color :").append(resCode).append(" ").append(colorSpec)
+ .append(CMD_SEPARATOR);
+ }
+ return cmd.toString();
+ }
+
+ @Override
+ public String setBackgroundColour(Color col)
+ {
+ return "set bgColor " + ColorUtils.toTkCode(col);
+ }
+
+ @Override
+ protected String getColourCommand(AtomSpecModel colourData,
+ String colourCode)
+ {
+ return "color " + colourData.getAtomSpecX() + " " + colourCode;
+ }
+
+ @Override
+ public String focusView()
+ {
+ return "view";
+ }
+
+}
package jalview.ext.rbvi.chimera;
import jalview.api.AlignmentViewPanel;
-import jalview.api.SequenceRenderer;
import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
import jalview.datamodel.AlignmentI;
import jalview.gui.StructureViewer.ViewerType;
import jalview.httpserver.AbstractRequestHandler;
import jalview.io.DataSourceType;
-import jalview.schemes.ColourSchemeI;
-import jalview.schemes.ResidueProperties;
import jalview.structure.AtomSpec;
import jalview.structure.StructureMappingcommandSet;
import jalview.structure.StructureSelectionManager;
import jalview.structures.models.AAStructureBindingModel;
-import jalview.util.ColorUtils;
import jalview.util.MessageManager;
-import java.awt.Color;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
-import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
// Chimera clause to exclude alternate locations in atom selection
private static final String NO_ALTLOCS = "&~@.B-Z&~@.2-9";
- private static final String COLOURING_CHIMERA = MessageManager
- .getString("status.colouring_chimera");
-
private static final boolean debug = false;
private static final String PHOSPHORUS = "P";
private static final String ALPHACARBON = "CA";
- private List<String> chainNames = new ArrayList<>();
-
- private Hashtable<String, String> chainFile = new Hashtable<>();
-
/*
* Object through which we talk to Chimera
*/
int modelNumber = chimeraMaps.size() + 1;
String command = "setattr #" + modelNumber + " models name "
+ pe.getId();
- sendChimeraCommand(command, false);
+ executeCommand(command, false);
modelsToMap.add(new ChimeraModel(pe.getId(), ModelType.PDB_MODEL,
modelNumber, 0));
}
chimeraManager = new ChimeraManager(new StructureManager(true));
String viewerType = Cache.getProperty(Preferences.STRUCTURE_DISPLAY);
chimeraManager.setChimeraX(ViewerType.CHIMERAX.name().equals(viewerType));
-
+ setStructureCommands(new ChimeraCommands());
}
/**
}
/**
- * Tells Chimera to display only the specified chains
- *
- * @param toshow
- */
- public void 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)
- {
- int modelNumber = getModelNoForChain(chain);
- String showChainCmd = modelNumber == -1 ? ""
- : modelNumber + ":." + chain.split(":")[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();
- sendChimeraCommand(command, false);
- }
-
- /**
* Close down the Jalview viewer and listener, and (optionally) the associated
* Chimera window.
*/
releaseUIResources();
}
- @Override
- public void colourByChain()
- {
- colourBySequence = false;
- sendAsynchronousCommand("rainbow chain", COLOURING_CHIMERA);
- }
-
- /**
- * Constructs and sends a Chimera command to colour by charge
- * <ul>
- * <li>Aspartic acid and Glutamic acid (negative charge) red</li>
- * <li>Lysine and Arginine (positive charge) blue</li>
- * <li>Cysteine - yellow</li>
- * <li>all others - white</li>
- * </ul>
- */
- @Override
- public void colourByCharge()
- {
- colourBySequence = false;
- String command = chimeraManager.isChimeraX()
- ? "color white;color :ASP,GLU red;color :LYS,ARG blue;color :CYS yellow"
- : "color white;color red ::ASP;color red ::GLU;color blue ::LYS;color blue ::ARG;color yellow ::CYS";
- sendAsynchronousCommand(command, COLOURING_CHIMERA);
- }
-
/**
* {@inheritDoc}
*/
}
// allComs.append("; ~display all; chain @CA|P; ribbon ")
// .append(selectioncom.toString()).append("; focus");
- List<String> chimeraReplies = sendChimeraCommand(allComs.toString(),
+ List<String> chimeraReplies = executeCommand(allComs.toString(),
true);
for (String reply : chimeraReplies)
{
* @param command
* @param getResponse
*/
- public List<String> sendChimeraCommand(final String command,
+ @Override
+ public List<String> executeCommand(final String command,
boolean getResponse)
{
- if (chimeraManager == null)
+ if (chimeraManager == null || command == null)
{
// ? thread running after viewer shut down
return null;
String progressMsg);
/**
- * Sends a set of colour commands to the structure viewer
- *
- * @param colourBySequenceCommands
- */
- @Override
- protected void colourBySequence(
- StructureMappingcommandSet[] colourBySequenceCommands)
- {
- for (StructureMappingcommandSet cpdbbyseq : colourBySequenceCommands)
- {
- for (String command : cpdbbyseq.commands)
- {
- sendAsynchronousCommand(command, COLOURING_CHIMERA);
- }
- }
- }
-
- /**
- * @param files
- * @param sr
- * @param viewPanel
- * @return
- */
- @Override
- protected StructureMappingcommandSet[] getColourBySequenceCommands(
- String[] files, SequenceRenderer sr, AlignmentViewPanel viewPanel)
- {
- return ChimeraCommands.getColourBySequenceCommand(getSsm(), files,
- getSequence(), sr, viewPanel, chimeraManager.isChimeraX());
- }
-
- /**
* @param command
*/
protected void executeWhenReady(String command)
{
waitForChimera();
- sendChimeraCommand(command, false);
+ executeCommand(command, false);
waitForChimera();
}
return loadNotifiesHandled;
}
- @Override
- public void setJalviewColourScheme(ColourSchemeI cs)
- {
- colourBySequence = false;
-
- if (cs == null)
- {
- return;
- }
-
- viewerCommandHistory(false);
- StringBuilder command = new StringBuilder(128);
-
- List<String> residueSet = ResidueProperties.getResidues(isNucleotide(),
- false);
-
- /*
- * concatenate colour commands, one per residue symbol
- * Chimera format: color colorCode ::VAL
- * ChimeraX format: color :VAL colourCode
- */
- boolean chimeraX = chimeraManager.isChimeraX();
- for (String resName : residueSet)
- {
- char res = resName.length() == 3
- ? ResidueProperties.getSingleCharacterCode(resName)
- : resName.charAt(0);
- Color col = cs.findColour(res, 0, null, null, 0f);
- command.append("color ");
- String colorSpec = ColorUtils.toTkCode(col);
- if (chimeraX)
- {
- command.append(":").append(resName).append(" ").append(colorSpec);
- }
- else
- {
- command.append(colorSpec).append(" ::").append(resName);
- }
- command.append(";");
- }
-
- sendAsynchronousCommand(command.toString(), COLOURING_CHIMERA);
- viewerCommandHistory(true);
- }
-
/**
* called when the binding thinks the UI needs to be refreshed after a Chimera
* state change. this could be because structures were loaded, or because an
}
/**
- * Send the Chimera 'background solid <color>" command.
- *
- * @see https
- * ://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/background
- * .html
- * @param col
- */
- @Override
- public void setBackgroundColour(Color col)
- {
- viewerCommandHistory(false);
- String command = "set bgColor " + ColorUtils.toTkCode(col);
- chimeraManager.sendChimeraCommand(command, false);
- viewerCommandHistory(true);
- }
-
- /**
* Ask Chimera to save its session to the given file. Returns true if
* successful, else false.
*
* 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
*/
- sendChimeraCommand("open " + filepath, true);
+ executeCommand("open " + filepath, true);
// todo: test for failure - how?
return true;
}
/**
- * Returns a list of chains mapped in this viewer. Note this list is not
- * currently scoped per structure.
- *
- * @return
- */
- @Override
- public List<String> getChainNames()
- {
- return chainNames;
- }
-
- /**
- * Send a 'focus' command to Chimera to recentre the visible display
- */
- public void focusView()
- {
- sendChimeraCommand(chimeraManager.isChimeraX() ? "view" : "focus", false);
- }
-
- /**
* Send a 'show' command for all atoms in the currently selected columns
*
* TODO: pull up to abstract structure viewer interface
// fails for 'average.bfactor' (which is bad):
String cmd = "list residues attr '" + attName + "'";
- List<String> residues = sendChimeraCommand(cmd, true);
+ List<String> residues = executeCommand(cmd, true);
boolean featureAdded = createFeaturesForAttributes(attName, residues);
if (featureAdded)
return CHIMERA_FEATURE_GROUP;
}
- public Hashtable<String, String> getChainFile()
- {
- return chainFile;
- }
-
- public List<ChimeraModel> getChimeraModelByChain(String chain)
- {
- return chimeraMaps.get(chainFile.get(chain));
- }
-
- public int getModelNoForChain(String chain)
+ @Override
+ public int getModelNoForFile(String pdbFile)
{
- List<ChimeraModel> foundModels = getChimeraModelByChain(chain);
+ List<ChimeraModel> foundModels = chimeraMaps.get(pdbFile);
if (foundModels != null && !foundModels.isEmpty())
{
return foundModels.get(0).getModelNumber();
import java.io.File;
import java.util.ArrayList;
import java.util.List;
-import java.util.Vector;
-import javax.swing.JCheckBoxMenuItem;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
{
command = "";
}
- jmb.evalStateCommand(command);
- jmb.evalStateCommand("set hoverDelay=0.1");
+ jmb.executeCommand(command, false);
+ jmb.executeCommand("set hoverDelay=0.1", false);
jmb.setFinishedInit(true);
}
@Override
- void showSelectedChains()
- {
- Vector<String> toshow = new Vector<>();
- for (int i = 0; i < chainMenu.getItemCount(); i++)
- {
- if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
- {
- JCheckBoxMenuItem item = (JCheckBoxMenuItem) chainMenu.getItem(i);
- if (item.isSelected())
- {
- toshow.addElement(item.getText());
- }
- }
- }
- jmb.centerViewer(toshow);
- }
-
- @Override
public void closeViewer(boolean closeExternalViewer)
{
// Jmol does not use an external viewer
try
{
- jmb.evalStateCommand(command);
+ jmb.executeCommand(command, false);
} catch (OutOfMemoryError oomerror)
{
new OOMWarning("When trying to add structures to the Jmol viewer!",
import java.util.Collections;
import java.util.List;
-import javax.swing.JCheckBoxMenuItem;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
}
/**
- * Show only the selected chain(s) in the viewer
- */
- @Override
- void showSelectedChains()
- {
- List<String> toshow = new ArrayList<>();
- for (int i = 0; i < chainMenu.getItemCount(); i++)
- {
- if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
- {
- JCheckBoxMenuItem item = (JCheckBoxMenuItem) chainMenu.getItem(i);
- if (item.isSelected())
- {
- toshow.add(item.getText());
- }
- }
- }
- jmb.showChains(toshow);
- }
-
- /**
* Close down this instance of Jalview's Chimera viewer, giving the user the
* option to close the associated Chimera window (process). They may wish to
* keep it open until they have had an opportunity to save any work.
String chid = new String(
pdb.getId() + ":" + pdb.getChains().elementAt(i).id);
jmb.getChainNames().add(chid);
- jmb.getChainFile().put(chid, file);
+ jmb.addChainFile(chid, file);
}
}
--- /dev/null
+package jalview.gui;
+
+import jalview.gui.StructureViewer.ViewerType;
+
+/**
+ * A class for the gui frame through which Jalview interacts with the ChimeraX
+ * structure viewer. Mostly the same as ChimeraViewFrame with a few overrides
+ * for the differences.
+ *
+ * @author gmcarstairs
+ *
+ */
+public class ChimeraXViewFrame extends ChimeraViewFrame
+{
+
+ @Override
+ public ViewerType getViewerType()
+ {
+ return null;// ViewerType.CHIMERAX;
+ }
+
+ @Override
+ protected String getViewerName()
+ {
+ return "ChimeraX";
+ }
+
+}
protected void sendAsynchronousCommand(final String command,
final String progressMsg)
{
+ final JalviewStructureDisplayI theViewer = getViewer();
final long handle = progressMsg == null ? 0
- : getViewer().startProgressBar(progressMsg);
+ : theViewer.startProgressBar(progressMsg);
SwingUtilities.invokeLater(new Runnable()
{
@Override
{
try
{
- sendChimeraCommand(command, false);
+ executeCommand(command, false);
} finally
{
if (progressMsg != null)
{
- getViewer().stopProgressBar(null, handle);
+ theViewer.stopProgressBar(null, handle);
}
}
}
--- /dev/null
+package jalview.gui;
+
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.structure.StructureSelectionManager;
+
+public class JalviewChimeraXBindingModel extends JalviewChimeraBindingModel
+{
+
+ public JalviewChimeraXBindingModel(ChimeraViewFrame chimeraViewFrame,
+ StructureSelectionManager ssm, PDBEntry[] pdbentry,
+ SequenceI[][] sequenceIs, DataSourceType protocol)
+ {
+ super(chimeraViewFrame, ssm, pdbentry, sequenceIs, protocol);
+ }
+
+}
}
}
- abstract void showSelectedChains();
-
/**
* Action on selecting one of Jalview's registered colour schemes
*/
ColourSchemeI cs = ColourSchemes.getInstance()
.getColourScheme(colourSchemeName, getAlignmentPanel().av, al,
null);
- getBinding().setJalviewColourScheme(cs);
+ getBinding().colourByJalviewColourScheme(cs);
}
/**
buildColourMenu();
}
- @Override
- public void setJalviewColourScheme(ColourSchemeI cs)
- {
- getBinding().setJalviewColourScheme(cs);
- }
-
/**
* Sends commands to the structure viewer to superimpose structures based on
* currently associated alignments. May optionally return an error message for
// default does nothing
}
+ /**
+ * Show only the selected chain(s) in the viewer
+ */
+ protected void showSelectedChains()
+ {
+ List<String> toshow = new ArrayList<>();
+ for (int i = 0; i < chainMenu.getItemCount(); i++)
+ {
+ if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
+ {
+ JCheckBoxMenuItem item = (JCheckBoxMenuItem) chainMenu.getItem(i);
+ if (item.isSelected())
+ {
+ toshow.add(item.getText());
+ }
+ }
+ }
+ getBinding().showChains(toshow);
+ }
+
}
import jalview.structure.AtomSpec;
import jalview.structure.StructureListener;
import jalview.structure.StructureMapping;
-import jalview.structure.StructureMappingcommandSet;
import jalview.structure.StructureSelectionManager;
import jalview.util.HttpUtils;
// Form a colour command from the given alignment panel for each distinct
// structure
- ArrayList<String[]> ccomands = new ArrayList<String[]>();
- ArrayList<String> pdbfn = new ArrayList<String>();
- StructureMappingcommandSet[] colcommands = JmolCommands
- .getColourBySequenceCommand(ssm, modelSet, sequence, sr,
+ ArrayList<String[]> ccomands = new ArrayList<>();
+ ArrayList<String> pdbfn = new ArrayList<>();
+ String[] colcommands = new JmolCommands()
+ .colourBySequence(ssm, modelSet, sequence, sr,
(AlignmentViewPanel) source);
if (colcommands == null)
{
return;
}
int sz = 0;
- for (jalview.structure.StructureMappingcommandSet ccset : colcommands)
+ // for (jalview.structure.StructureMappingcommandSet ccset : colcommands)
+ for (String command : colcommands)
{
- sz += ccset.commands.length;
- ccomands.add(ccset.commands);
- pdbfn.add(ccset.mapping);
+ // sz += ccset.commands.length;
+ // ccomands.add(command); // ccset.commands);
+ // pdbfn.add(ccset.mapping);
}
String mclass, mhandle;
--- /dev/null
+package jalview.structure;
+
+/**
+ * A base class holding methods useful to all classes that implement commands
+ * for structure viewers
+ *
+ * @author gmcarstairs
+ *
+ */
+public abstract class StructureCommandsBase implements StructureCommandsI
+{
+}
--- /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;
+ }
+}
--- /dev/null
+package jalview.structure;
+
+import jalview.api.AlignmentViewPanel;
+import jalview.api.SequenceRenderer;
+import jalview.datamodel.SequenceI;
+
+import java.awt.Color;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Methods that generate commands that can be sent to a molecular structure
+ * viewer program (e.g. Jmol, Chimera, ChimeraX)
+ *
+ * @author gmcarstairs
+ *
+ */
+public interface StructureCommandsI
+{
+
+ /**
+ * Returns the command to colour by chain
+ *
+ * @return
+ */
+ String colourByChain();
+
+ /**
+ * Returns the command to colour residues using a charge-based scheme:
+ * <ul>
+ * <li>Aspartic acid and Glutamic acid (negative charge) red</li>
+ * <li>Lysine and Arginine (positive charge) blue</li>
+ * <li>Cysteine - yellow</li>
+ * <li>all others - white</li>
+ * </ul>
+ *
+ * @return
+ */
+ String colourByCharge();
+
+ /**
+ * Returns the command to colour residues with the colours provided in the
+ * map, one per three letter residue code
+ *
+ * @param colours
+ * @return
+ */
+ String colourByResidues(Map<String, Color> colours);
+
+ /**
+ * Returns the command to set the background colour of the structure viewer
+ *
+ * @param col
+ * @return
+ */
+ String setBackgroundColour(Color col);
+
+ /**
+ * Returns commands to colour mapped residues of structures according to
+ * Jalview's colouring (including feature colouring if applied)
+ *
+ * @param structureSelectionManager
+ * @param files
+ * @param seqs
+ * @param sr
+ * @param alignmentv
+ * @return
+ */
+ String[] colourBySequence(
+ StructureSelectionManager structureSelectionManager,
+ String[] files, SequenceI[][] seqs, SequenceRenderer sr,
+ AlignmentViewPanel alignmentv);
+
+ /**
+ * Returns a command to centre the display in the structure viewer
+ *
+ * @return
+ */
+ String focusView();
+
+ /**
+ * Returns a command to show only the selected chains. The items in the input
+ * list should be formatted as "modelno:chainid".
+ *
+ * @param toShow
+ * @return
+ */
+ String showChains(List<String> toShow);
+
+}
import jalview.datamodel.SequenceI;
import jalview.io.DataSourceType;
import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ResidueProperties;
import jalview.structure.AtomSpec;
+import jalview.structure.StructureCommandsI;
import jalview.structure.StructureListener;
import jalview.structure.StructureMapping;
-import jalview.structure.StructureMappingcommandSet;
import jalview.structure.StructureSelectionManager;
import jalview.util.Comparison;
import jalview.util.MessageManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+
+import javax.swing.SwingUtilities;
/**
*
extends SequenceStructureBindingModel
implements StructureListener, StructureSelectionManagerProvider
{
+ private static final String COLOURING_STRUCTURES = MessageManager
+ .getString("status.colouring_structures");
+
/*
* the Jalview panel through which the user interacts
* with the structure viewer
*/
private JalviewStructureDisplayI viewer;
+ /*
+ * helper that generates command syntax
+ */
+ private StructureCommandsI commandGenerator;
+
private StructureSelectionManager ssm;
/*
+ * modelled chains, formatted as "pdbid:chainCode"
+ */
+ private List<String> chainNames;
+
+ /*
+ * lookup of pdb file name by key "pdbid:chainCode"
+ */
+ private Map<String, String> chainFile;
+
+ /*
* distinct PDB entries (pdb files) associated
* with sequences
*/
{
this.ssm = ssm;
this.sequence = seqs;
+ chainNames = new ArrayList<>();
+ chainFile = new HashMap<>();
}
/**
PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
DataSourceType protocol)
{
- this.ssm = ssm;
- this.sequence = sequenceIs;
+ this(ssm, sequenceIs);
this.nucleotide = Comparison.isNucleotide(sequenceIs);
this.pdbEntry = pdbentry;
this.protocol = protocol;
}
/**
- * Returns a list of chains mapped in this viewer.
+ * Returns a list of chains mapped in this viewer, formatted as
+ * "pdbid:chainCode"
*
* @return
*/
- public abstract List<String> getChainNames();
+ public List<String> getChainNames()
+ {
+ return chainNames;
+ }
/**
* Returns the Jalview panel hosting the structure viewer (if any)
viewer = v;
}
- public abstract void setJalviewColourScheme(ColourSchemeI cs);
-
/**
* Constructs and sends a command to align structures against a reference
* structure, based on one or more sequence alignments. May optionally return
public abstract String superposeStructures(AlignmentI[] alignments,
int[] structureIndices, HiddenColumns[] hiddenCols);
- public abstract void setBackgroundColour(Color col);
-
- protected abstract StructureMappingcommandSet[] getColourBySequenceCommands(
- String[] files, SequenceRenderer sr, AlignmentViewPanel avp);
-
/**
* returns the current sequenceRenderer that should be used to colour the
* structures
public abstract SequenceRenderer getSequenceRenderer(
AlignmentViewPanel alignment);
- protected abstract void colourBySequence(
- StructureMappingcommandSet[] colourBySequenceCommands);
+ /**
+ * Sends a command to the structure viewer to colour each chain with a
+ * distinct colour (to the extent supported by the viewer)
+ */
+ public void colourByChain()
+ {
+ colourBySequence = false;
+
+ // TODO: JAL-628 colour chains distinctly across all visible models
+
+ executeCommand(commandGenerator.colourByChain(), false,
+ COLOURING_STRUCTURES);
+ }
+
+ /**
+ * Sends a command to the structure viewer to colour each chain with a
+ * distinct colour (to the extent supported by the viewer)
+ */
+ public void colourByCharge()
+ {
+ colourBySequence = false;
+
+ executeCommand(commandGenerator.colourByCharge(), false,
+ COLOURING_STRUCTURES);
+ }
+
+ /**
+ * Sends a command to the structure to apply a colour scheme (defined in
+ * Jalview but not necessarily applied to the alignment), which defines a
+ * colour per residue letter. More complex schemes (e.g. that depend on
+ * consensus) cannot be used here and are ignored.
+ *
+ * @param cs
+ */
+ public void colourByJalviewColourScheme(ColourSchemeI cs)
+ {
+ colourBySequence = false;
+
+ if (cs == null || !cs.isSimple())
+ {
+ return;
+ }
+
+ /*
+ * build a map of {Residue3LetterCode, Color}
+ */
+ Map<String, Color> colours = new HashMap<>();
+ List<String> residues = ResidueProperties.getResidues(isNucleotide(),
+ false);
+ for (String resName : residues)
+ {
+ char res = resName.length() == 3
+ ? ResidueProperties.getSingleCharacterCode(resName)
+ : resName.charAt(0);
+ Color colour = cs.findColour(res, 0, null, null, 0f);
+ colours.put(resName, colour);
+ }
+
+ /*
+ * pass to the command constructor, and send the command
+ */
+ String cmd = commandGenerator.colourByResidues(colours);
+ executeCommand(cmd, false, COLOURING_STRUCTURES);
+ }
+
+ public void setBackgroundColour(Color col)
+ {
+ String cmd = commandGenerator.setBackgroundColour(col);
+ executeCommand(cmd, false, null);
+ }
+
+ /**
+ * Sends one command to the structure viewer. If {@code getReply} is true, the
+ * command is sent synchronously, otherwise in a deferred thread.
+ * <p>
+ * If a progress message is supplied, this is displayed before command
+ * execution, and removed afterwards.
+ *
+ * @param cmd
+ * @param getReply
+ * @param msg
+ * @return
+ */
+ private List<String> executeCommand(String cmd, boolean getReply,
+ String msg)
+ {
+ if (getReply)
+ {
+ return executeSynchronous(cmd, msg, getReply);
+ }
+ else
+ {
+ executeAsynchronous(cmd, msg);
+ 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.
+ *
+ * @param cmd
+ * @param msg
+ * @param getReply
+ * @return
+ */
+ private List<String> executeSynchronous(String cmd, String msg, boolean getReply)
+ {
+ 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);
+ }
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * @param cmd
+ * @param msg
+ */
+ private void executeAsynchronous(String cmd, String msg)
+ {
+ final JalviewStructureDisplayI theViewer = getViewer();
+ final long handle = msg == null ? 0 : theViewer.startProgressBar(msg);
- public abstract void colourByChain();
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ executeCommand(cmd, false);
+ } finally
+ {
+ if (msg != null)
+ {
+ theViewer.stopProgressBar(null, handle);
+ }
+ }
+ }
+ });
+ }
+
+ protected abstract List<String> executeCommand(String command,
+ boolean getReply);
- public abstract void colourByCharge();
+ protected List<String> executeCommands(boolean getReply,
+ String... commands)
+ {
+ List<String> response = null;
+ for (String cmd : commands)
+ {
+ response = executeCommand(cmd, getReply);
+ }
+ return response;
+ }
/**
* colour any structures associated with sequences in the given alignment
SequenceRenderer sr = getSequenceRenderer(alignmentv);
- StructureMappingcommandSet[] colourBySequenceCommands = getColourBySequenceCommands(
- files, sr, alignmentv);
- colourBySequence(colourBySequenceCommands);
+ String[] colourBySequenceCommands = commandGenerator
+ .colourBySequence(getSsm(), files, getSequence(), sr,
+ alignmentv);
+ executeCommands(false, colourBySequenceCommands);
+ }
+
+ /**
+ * Centre the display in the structure viewer
+ */
+ public void focusView()
+ {
+ executeCommand(commandGenerator.focusView(), false);
+ }
+
+ /**
+ * Generates and executes a command to show only specified chains in the
+ * structure viewer. The list of chains to show should contain entries
+ * formatted as "pdbid:chaincode".
+ *
+ * @param toShow
+ */
+ public void showChains(List<String> toShow)
+ {
+ // todo or reformat toShow list entries as modelNo:pdbId:chainCode ?
+
+ /*
+ * Reformat the pdbid:chainCode values as modelNo:chainCode
+ * since this is what is needed to construct the viewer command
+ * todo: find a less messy way to do this
+ */
+ List<String> showThese = new ArrayList<>();
+ for (String chainId : toShow)
+ {
+ String[] tokens = chainId.split("\\:");
+ if (tokens.length == 2)
+ {
+ String pdbFile = getFileForChain(chainId);
+ int modelNo = getModelNoForFile(pdbFile);
+ String model = modelNo == -1 ? "" : String.valueOf(modelNo);
+ showThese.add(model + ":" + tokens[1]);
+ }
+ }
+ executeCommand(commandGenerator.showChains(showThese), false);
}
+ /**
+ * Answers the structure viewer's model number given a PDB file name. Returns
+ * -1 if model number is not found.
+ *
+ * @param chainId
+ * @return
+ */
+ protected abstract int getModelNoForFile(String chainId);
+
public boolean hasFileLoadingError()
{
return fileLoadingError != null && fileLoadingError.length() > 0;
? ap.getFeatureRenderer()
: null;
}
+
+ protected void setStructureCommands(StructureCommandsI cmd)
+ {
+ commandGenerator = cmd;
+ }
+
+ /**
+ * Records association of one chain id (formatted as "pdbid:chainCode") with
+ * the corresponding PDB file name
+ *
+ * @param chainId
+ * @param fileName
+ */
+ public void addChainFile(String chainId, String fileName)
+ {
+ chainFile.put(chainId, fileName);
+ }
+
+ /**
+ * Returns the PDB filename for the given chain id (formatted as
+ * "pdbid:chainCode"), or null if not found
+ *
+ * @param chainId
+ * @return
+ */
+ protected String getFileForChain(String chainId)
+ {
+ return chainFile.get(chainId);
+ }
}
import jalview.gui.SequenceRenderer;
import jalview.schemes.JalviewColourScheme;
import jalview.structure.StructureMapping;
-import jalview.structure.StructureMappingcommandSet;
import jalview.structure.StructureSelectionManager;
import java.util.HashMap;
// need some mappings!
- StructureMappingcommandSet[] commands = JmolCommands
- .getColourBySequenceCommand(ssm, files, seqs, sr, af.alignPanel);
+ String[] commands = new JmolCommands().colourBySequence(ssm, files,
+ seqs, sr, af.alignPanel);
+ assertEquals(commands.length, 0);
}
@Test(groups = { "Functional" })
SequenceI[][] seqs = new SequenceI[][] { { seq1 }, { seq2 } };
String[] files = new String[] { "seq1.pdb", "seq2.pdb" };
StructureSelectionManager ssm = new StructureSelectionManager();
-
+
/*
* map residues 1-10 to residues 21-30 (atoms 105-150) in structures
*/
- HashMap<Integer, int[]> map = new HashMap<Integer, int[]>();
+ HashMap<Integer, int[]> map = new HashMap<>();
for (int pos = 1; pos <= seq1.getLength(); pos++)
{
map.put(pos, new int[] { 20 + pos, 5 * (20 + pos) });
StructureMapping sm2 = new StructureMapping(seq2, "seq2.pdb", "pdb2",
"B", map, null);
ssm.addStructureMapping(sm2);
-
- StructureMappingcommandSet[] commands = JmolCommands
- .getColourBySequenceCommand(ssm, files, seqs, sr, af.alignPanel);
+
+ String[] commands = new JmolCommands().colourBySequence(ssm, files,
+ seqs, sr, af.alignPanel);
assertEquals(commands.length, 2);
- assertEquals(commands[0].commands.length, 1);
- String chainACommand = commands[0].commands[0];
+ String chainACommand = commands[0];
// M colour is #82827d == (130, 130, 125) (see strand.html help page)
- assertTrue(chainACommand
- .contains("select 21:A/1.1;color[130,130,125]")); // first one
+ assertTrue(
+ chainACommand.contains("select 21:A/1.1;color[130,130,125]")); // first
+ // one
// H colour is #60609f == (96, 96, 159)
assertTrue(chainACommand.contains(";select 22:A/1.1;color[96,96,159]"));
// hidden columns are Gray (128, 128, 128)
assertTrue(chainACommand
.contains(";select 23-25:A/1.1;color[128,128,128]"));
// S and G are both coloured #4949b6 == (73, 73, 182)
- assertTrue(chainACommand
- .contains(";select 26-30:A/1.1;color[73,73,182]"));
+ assertTrue(
+ chainACommand.contains(";select 26-30:A/1.1;color[73,73,182]"));
- String chainBCommand = commands[1].commands[0];
+ String chainBCommand = commands[1];
// M colour is #82827d == (130, 130, 125)
- assertTrue(chainBCommand
- .contains("select 21:B/2.1;color[130,130,125]"));
+ assertTrue(
+ chainBCommand.contains("select 21:B/2.1;color[130,130,125]"));
// V colour is #ffff00 == (255, 255, 0)
- assertTrue(chainBCommand
-.contains(";select 22:B/2.1;color[255,255,0]"));
+ assertTrue(chainBCommand.contains(";select 22:B/2.1;color[255,255,0]"));
// hidden columns are Gray (128, 128, 128)
assertTrue(chainBCommand
.contains(";select 23-25:B/2.1;color[128,128,128]"));
// S and G are both coloured #4949b6 == (73, 73, 182)
- assertTrue(chainBCommand
- .contains(";select 26-30:B/2.1;color[73,73,182]"));
+ assertTrue(
+ chainBCommand.contains(";select 26-30:B/2.1;color[73,73,182]"));
}
}
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
-import jalview.gui.JvOptionPane;
import jalview.gui.SequenceRenderer;
import jalview.schemes.JalviewColourScheme;
import jalview.structure.StructureMapping;
-import jalview.structure.StructureMappingcommandSet;
import jalview.structure.StructureSelectionManager;
import java.awt.Color;
import java.util.List;
import java.util.Map;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class ChimeraCommandsTest
{
- @BeforeClass(alwaysRun = true)
- public void setUpJvOptionPane()
- {
- JvOptionPane.setInteractiveMode(false);
- JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
- }
-
@Test(groups = { "Functional" })
public void testBuildColourCommands()
{
// 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 command = ChimeraCommands.buildColourCommands(map, false).get(0);
+ String command = new ChimeraCommands().buildColourCommands(map).get(0);
assertEquals(
command,
"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");
* feature name gets a jv_ namespace prefix
* feature value is quoted in case it contains spaces
*/
- assertEquals(commands.get(0), "setattr r jv_chain 'X' #0:8-20.A");
+ assertEquals(commands.get(0), "setattr res jv_chain 'X' #0:8-20.A");
// add same feature value, overlapping range
ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 3, 9, "A");
commands = ChimeraCommands.buildSetAttributeCommands(featuresMap,
false);
assertEquals(1, commands.size());
- assertEquals(commands.get(0), "setattr r jv_chain 'X' #0:3-25.A");
+ assertEquals(commands.get(0), "setattr res jv_chain 'X' #0:3-25.A");
// same feature value and model, different chain
ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 21, 25, "B");
false);
assertEquals(1, commands.size());
assertEquals(commands.get(0),
- "setattr r jv_chain 'X' #0:3-25.A,21-25.B|#1:26-30.A");
+ "setattr res jv_chain 'X' #0:3-25.A,21-25.B|#1:26-30.A");
// same feature, different value
ChimeraCommands.addAtomSpecRange(featureValues, "Y", 0, 40, 50, "A");
// commands are ordered by feature type but not by value
// so use contains to test for the expected command:
assertTrue(commands
- .contains("setattr r jv_chain 'X' #0:3-25.A,21-25.B|#1:26-30.A"));
- assertTrue(commands.contains("setattr r jv_chain 'Y' #0:40-50.A"));
+ .contains(
+ "setattr res jv_chain 'X' #0:3-25.A,21-25.B|#1:26-30.A"));
+ assertTrue(commands.contains("setattr res jv_chain 'Y' #0:40-50.A"));
featuresMap.clear();
featureValues.clear();
commands = ChimeraCommands.buildSetAttributeCommands(featuresMap,
false);
assertTrue(commands
- .contains("setattr r jv_side_chain_binding_ '<html>metal <a href=\"http:a.b.c/x\"> 'ion!' #0:7-15.A"));
+ .contains(
+ "setattr res jv_side_chain_binding_ '<html>metal <a href=\"http:a.b.c/x\"> 'ion!' #0:7-15.A"));
}
/**
"B", map, null);
ssm.addStructureMapping(sm2);
- StructureMappingcommandSet[] commands = ChimeraCommands
- .getColourBySequenceCommand(ssm, files, seqs, sr, af.alignPanel,
- false);
+ String[] commands = new ChimeraCommands()
+ .colourBySequence(ssm, files, seqs, sr, af.alignPanel);
assertEquals(1, commands.length);
- assertEquals(1, commands[0].commands.length);
- String theCommand = commands[0].commands[0];
+ String theCommand = commands[0];
// M colour is #82827d (see strand.html help page)
assertTrue(theCommand.contains("color #82827d #0:21.A|#1:21.B"));
// H colour is #60609f
/*
* ask Chimera for its residue attribute names
*/
- List<String> reply = binding.sendChimeraCommand("list resattr", true);
+ List<String> reply = binding.executeCommand("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"));
* ask Chimera for residues with an attribute
* 91 and 96 on sequence --> residues 40 and 45 on chains A and B
*/
- reply = binding.sendChimeraCommand(
+ reply = binding.executeCommand(
"list resi att jv_metal_ion_binding_site", true);
assertEquals(reply.size(), 4);
assertTrue(reply
* check attributes with score values
* sequence positions 62 and 65 --> residues 11 and 14 on chains A and B
*/
- reply = binding.sendChimeraCommand("list resi att jv_kd", true);
+ reply = binding.executeCommand("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.sendChimeraCommand(
+ reply = binding.executeCommand(
"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"));
acf3.addMap(new Sequence("s3", "ttt"), new Sequence("p3", "p"),
new MapList(new int[] { 1, 3 }, new int[] { 1, 1 }, 1, 1));
- List<AlignedCodonFrame> set1 = new ArrayList<AlignedCodonFrame>();
+ List<AlignedCodonFrame> set1 = new ArrayList<>();
set1.add(acf1);
set1.add(acf2);
- List<AlignedCodonFrame> set2 = new ArrayList<AlignedCodonFrame>();
+ List<AlignedCodonFrame> set2 = new ArrayList<>();
set2.add(acf2);
set2.add(acf3);
assertEquals(1, pmap.getSeqs().size());
assertEquals("4IM2|A", pmap.getSeqs().get(0).getName());
- List<int[]> structuremap1 = new ArrayList(
+ List<int[]> structuremap1 = new ArrayList<>(
sm.getMapping(P4IM2_MISSING)[0]
.getPDBResNumRanges(seq.getStart(), seq.getEnd()));
// positional mapping to atoms for color by structure is still wrong, even
// though panel looks correct.
- StructureMappingcommandSet smcr[] = JmolCommands
- .getColourBySequenceCommand(apssm,
+ String[] smcr = new JmolCommands().colourBySequence(apssm,
new String[]
{ pdbe.getFile() },
new SequenceI[][]
new SequenceRenderer(alf.alignPanel.getAlignViewport()),
alf.alignPanel);
// Expected - all residues are white
- for (StructureMappingcommandSet smm : smcr)
+ for (String c : smcr)
{
- for (String c : smm.commands)
- {
- System.out.println(c);
- }
+ assertTrue(c.contains("color[255,255,255]"));
+ System.out.println(c);
}
}
import jalview.gui.JvOptionPane;
import jalview.io.DataSourceType;
import jalview.io.FileFormats;
-import jalview.schemes.ColourSchemeI;
import jalview.structure.AtomSpec;
-import jalview.structure.StructureMappingcommandSet;
import jalview.structure.StructureSelectionManager;
import jalview.structures.models.AAStructureBindingModel.SuperposeData;
-import java.awt.Color;
import java.io.IOException;
import java.util.Arrays;
import java.util.BitSet;
@Override
public void updateColours(Object source)
{
- // TODO Auto-generated method stub
-
}
@Override
public void releaseReferences(Object svl)
{
- // TODO Auto-generated method stub
-
}
@Override
public String[] getStructureFiles()
{
- // TODO Auto-generated method stub
return null;
}
public String superposeStructures(AlignmentI[] alignments,
int[] structureIndices, HiddenColumns[] hiddenCols)
{
- // TODO Auto-generated method stub
return null;
}
@Override
- public void setJalviewColourScheme(ColourSchemeI cs)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void setBackgroundColour(Color col)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
public void highlightAtoms(List<AtomSpec> atoms)
{
- // TODO Auto-generated method stub
-
}
@Override
public SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment)
{
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- protected StructureMappingcommandSet[] getColourBySequenceCommands(
- String[] files, SequenceRenderer sr, AlignmentViewPanel avp)
- {
- // TODO Auto-generated method stub
return null;
}
-
+
@Override
- public List<String> getChainNames()
+ protected List<String> executeCommand(String command,
+ boolean getReply)
{
- // TODO Auto-generated method stub
return null;
}
-
- @Override
- protected void colourBySequence(
- StructureMappingcommandSet[] colourBySequenceCommands)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void colourByCharge()
- {
- // TODO Auto-generated method stub
-
- }
-
+
@Override
- public void colourByChain()
+ protected int getModelNoForFile(String chainId)
{
- // TODO Auto-generated method stub
-
+ return 0;
}
};
String[][] chains = binder.getChains();
}
@Override
- public List<String> getChainNames()
- {
- return null;
- }
-
- @Override
- public void setJalviewColourScheme(ColourSchemeI cs)
- {
- }
-
- @Override
public String superposeStructures(AlignmentI[] als, int[] alm,
HiddenColumns[] alc)
{
}
@Override
- public void setBackgroundColour(Color col)
- {
- }
-
- @Override
- protected StructureMappingcommandSet[] getColourBySequenceCommands(
- String[] files, SequenceRenderer sr, AlignmentViewPanel avp)
- {
- return null;
- }
-
- @Override
public SequenceRenderer getSequenceRenderer(
AlignmentViewPanel alignment)
{
}
@Override
- protected void colourBySequence(
- StructureMappingcommandSet[] colourBySequenceCommands)
- {
- }
-
- @Override
- public void colourByChain()
+ protected List<String> executeCommand(String command,
+ boolean getReply)
{
+ return null;
}
@Override
- public void colourByCharge()
+ protected int getModelNoForFile(String chainId)
{
+ return 0;
}
};
}