#
jalviewDir = .
-
#JAVA_VERSION = 1.8
JAVA_VERSION = 11
label.create_image_of = Create {0} image of {1}
label.click_to_edit = Click to edit, right-click for menu
label.by_annotation_tooltip = Annotation Colour is configured from the main Colour menu
+label.show_alignment_only = Show alignment only
+label.hide_hidden_regions = Hide hidden columns / sequences
label.show_linked_features = Show {0} features
label.on_top = on top
label.include_linked_features = Include {0} features
label.check_file_matches_sequence_ids_alignment = Comprobar que el fichero coincide con el ID de la secuencia en el alineamiento.
label.problem_reading_tcoffee_score_file = Problema de lectura del fichero de puntuaciones T-COFFEE
label.source_to_target = {0} a {1}
-label.per_sequence_only= Sólo por secuencia
+label.per_sequence_
+= Sólo por secuencia
label.to_file = a fichero
label.to_textbox = a cuadro de texto
label.jalview = Jalview
label.create_image_of = Crear imagen {0} de {1}
label.click_to_edit = Haga clic para editar, clic en el botón derecho para ver el menú
label.by_annotation_tooltip = El color de anotación se configura desde el menú principal de colores
+label.show_alignment_only = Mostrar solo alineamiento
+label.hide_hidden_regions = Ocultar columnas / secuencias ocultas
label.show_linked_features = Características de {0}
label.on_top = encima
label.include_linked_features = Incluir características de {0}
* @return displayed name for the view
*/
String getViewName();
+
+ /**
+ * Answers the title of the panel
+ *
+ * @return
+ */
+ String getTitle();
+
+ /**
+ * Make/Unmake this alignment panel the current input focus
+ *
+ * @param b
+ */
+ void setSelected(boolean b);
}
}
+ @Override
+ public String getTitle()
+ {
+ return alignFrame.getTitle();
+ }
+
+ @Override
+ public void setSelected(boolean b)
+ {
+ // noop
+ }
+
}
void centerViewer()
{
- Vector<String> toshow = new Vector<>();
+ Vector<String> toHide = new Vector<>();
for (int i = 0; i < chainMenu.getItemCount(); i++)
{
if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
{
CheckboxMenuItem item = (CheckboxMenuItem) chainMenu.getItem(i);
- if (item.getState())
+ if (!item.getState())
{
- toshow.addElement(item.getLabel());
+ toHide.addElement(item.getLabel());
}
}
}
- jmb.showChains(toshow);
+ jmb.setChainsToHide(toHide);
+ jmb.centerViewer();
}
void closeViewer()
else if (evt.getSource() == seqColour)
{
setEnabled(seqColour);
- jmb.colourBySequence(ap);
+ jmb.updateStructureColours(ap);
}
else if (!allChainsSelected)
{
public void updateColours(Object source)
{
AlignmentPanel panel = (AlignmentPanel) source;
- jmb.colourBySequence(panel);
+ jmb.updateStructureColours(panel);
}
public void updateTitleAndMenus()
return;
}
setChainMenuItems(jmb.getChainNames());
- jmb.colourBySequence(ap);
+ jmb.updateStructureColours(ap);
setTitle(jmb.getViewerTitle());
}
public void updateColours(Object source)
{
AlignmentPanel ap = (AlignmentPanel) source;
- colourBySequence(ap);
+ updateStructureColours(ap);
}
@Override
import org.jmol.c.CBK;
import org.jmol.viewer.Viewer;
+import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.api.FeatureRenderer;
import jalview.api.SequenceRenderer;
import jalview.io.DataSourceType;
import jalview.io.StructureFile;
import jalview.structure.AtomSpec;
+import jalview.structure.AtomSpecModel;
import jalview.structure.StructureCommand;
import jalview.structure.StructureCommandI;
import jalview.structure.StructureSelectionManager;
return getViewerTitle("Jmol", true);
}
+ /**
+ * prepare the view for a given set of models/chains. chainList contains strings
+ * of the form 'pdbfilename:Chaincode'
+ *
+ * @deprecated now only used by applet code
+ */
+ @Deprecated
+ public void centerViewer()
+ {
+ StringBuilder cmd = new StringBuilder(128);
+ int mlength, p;
+ for (String lbl : chainsToHide)
+ {
+ 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) + " /"
+ + (getModelIdForFile(getFileForChain(lbl))) + " or ");
+ }
+ if (cmd.length() > 0)
+ {
+ cmd.setLength(cmd.length() - 4);
+ }
+ // todo: revised command is untested - but this method is obsolete anyway
+ String command = "select *;hide " + cmd + ";cartoon;center " + cmd;
+ executeCommand(new StructureCommand(command), false);
+ }
+
private String jmolScript(String script)
{
Cache.log.debug(">>Jmol>> " + script);
String s = jmolViewer.evalStringQuiet(script); // scriptWait(script); BH
Cache.log.debug("<<Jmol<< " + s);
-
return s;
}
@Override
public synchronized String[] getStructureFiles()
{
+ if (modelFileNames != null)
+ {
+ return modelFileNames;
+ }
if (jmolViewer == null)
{
return new String[0];
}
- if (modelFileNames == null)
+ List<String> mset = new ArrayList<>();
+ int modelCount = jmolViewer.ms.mc;
+ String filePath = null;
+ for (int i = 0; i < modelCount; ++i)
{
- int modelCount = jmolViewer.ms.mc;
- String filePath = null;
- List<String> mset = new ArrayList<>();
- for (int i = 0; i < modelCount; ++i)
+ /*
+ * defensive check for null as getModelFileName can return null
+ * even when model count ms.mc is > 0
+ */
+ filePath = jmolViewer.ms.getModelFileName(i);
+ if (filePath != null && !mset.contains(filePath))
{
- /*
- * defensive check for null as getModelFileName can return null
- * even when model count ms.mc is > 0
- */
- filePath = jmolViewer.ms.getModelFileName(i);
- if (filePath != null && !mset.contains(filePath))
- {
- mset.add(filePath);
- }
- }
- if (!mset.isEmpty())
- {
- modelFileNames = mset.toArray(new String[mset.size()]);
+ mset.add(filePath);
}
}
+ if (!mset.isEmpty())
+ {
+ modelFileNames = mset.toArray(new String[mset.size()]);
+ }
+
return modelFileNames;
}
}
@Override
+ public void showStructures(AlignViewportI av, boolean refocus)
+ {
+ String cmd = buildShowStructuresCommand(av, refocus);
+ executeCommand(new StructureCommand(cmd), false);
+ }
+
+ /**
+ * Builds a command to show parts of the structure, depending on whether
+ * <ul>
+ * <li>all structures or regions mapped to alignment only are shown</li>
+ * <li>all chains or only selected chains are shown</li>
+ * </ul>
+ *
+ * @param av
+ * @param refocus
+ * @return
+ */
+ protected String buildShowStructuresCommand(AlignViewportI av,
+ boolean refocus)
+ {
+ StringBuilder cmd = new StringBuilder(128);
+ if (!isShowAlignmentOnly())
+ {
+ cmd.append("display *");
+ }
+ else
+ {
+ AtomSpecModel model = getShownResidues(av);
+ String atomSpec = getCommandGenerator().getAtomSpec(model, false);
+
+ cmd.append("hide *;display ").append(atomSpec)
+ .append("; select displayed");
+ }
+
+ /*
+ * hide any chains not selected to be shown
+ */
+ if (!chainsToHide.isEmpty())
+ {
+ cmd.append("; hide add ");
+ boolean firstHide = true;
+ for (String pdbChain : chainsToHide)
+ {
+ String[] toks = pdbChain.split(":");
+ String chainId = toks[1];
+ String modelNo = getModelIdForFile(getFileForChain(pdbChain));
+ if ("".equals(modelNo))
+ {
+ continue;
+ }
+ if (!firstHide)
+ {
+ cmd.append(",");
+ }
+ firstHide = false;
+ cmd.append(":").append(chainId).append("/")
+ .append(String.valueOf(modelNo)).append(".1");
+ }
+ }
+
+ cmd.append("; cartoon only");
+ if (refocus)
+ {
+ cmd.append("; zoom 0");
+ }
+ return cmd.toString();
+ }
+
+ /**
+ * Answers a Jmol syntax style structure model specification. Model number 0, 1,
+ * 2... is formatted as "1.1", "2.1", "3.1" etc.
+ */
+ @Override
+ public String getModelSpec(int model)
+ {
+ return String.valueOf(model + 1) + ".1";
+ }
+
+ @Override
protected String getModelIdForFile(String pdbFile)
{
if (modelFileNames == null)
*/
public class JmolCommands extends StructureCommandsBase
{
+ private static final String COMMA = ",";
+
private static final StructureCommand SHOW_BACKBONE = new StructureCommand(
"select *; cartoons off; backbone");
private static final String SLASH = "/";
- /**
- * {@inheritDoc}
- *
- * @return
- */
@Override
public int getModelStartNo()
{
* Generates a Jmol atomspec string like
*
* <pre>
- * 2-5:A/1.1,8:A/1.1,5-10:B/2.1
+ * (61-64,70)&:A/1.1,(12-25,41-44)&:B/1.1,12:A/2.1
+ * for model 1, chain A, residues 61-64 and 70, chain B residues 12-25 and 41-44, model 2 chain A residue 12
* </pre>
*
+ * Note the brackets to group multiple residue ranges for the same chain
+ * (without bracketing, ranges would apply to all chains)
+ *
* Parameter {@code alphaOnly} is not used here - this restriction is made by
* a separate clause in the {@code compare} (superposition) command.
*/
{
StringBuilder sb = new StringBuilder(128);
- boolean first = true;
+ boolean firstChain = true;
for (String modelNo : model.getModels())
{
for (String chain : model.getChains(modelNo))
{
- for (int[] range : model.getRanges(modelNo, chain))
+ if (!firstChain)
{
- if (!first)
- {
- sb.append(PIPE);
- }
- first = false;
- if (range[0] == range[1])
+ sb.append(COMMA);
+ }
+ firstChain = false;
+ List<int[]> rangeList = model.getRanges(modelNo, chain);
+ if (rangeList.size() > 1)
+ {
+ sb.append("(");
+ }
+ boolean firstRange = true;
+ for (int[] range : rangeList)
+ {
+ if (!firstRange)
{
- sb.append(range[0]);
+ sb.append(COMMA);
}
- else
+ firstRange = false;
+ firstChain = false;
+ sb.append(range[0]);
+ if (range[0] != range[1])
{
- sb.append(range[0]).append(HYPHEN).append(range[1]);
+ sb.append(HYPHEN).append(range[1]);
}
- sb.append(COLON).append(chain.trim()).append(SLASH);
- sb.append(String.valueOf(modelNo)).append(".1");
}
+ if (rangeList.size() > 1)
+ {
+ sb.append(")&");
+ }
+ sb.append(COLON).append(chain.trim()).append(SLASH);
+ sb.append(String.valueOf(modelNo)).append(".1");
}
}
--- /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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * A class to model a Chimera or Jmol residue set, as
+ * {@code Map<modelNumber, Map<chainId, List<residueRange>>>}. This can then be
+ * traversed to generate the required display command in Chimera or Jmol syntax.
+ */
+public class AtomSpecModel
+{
+ private Map<Integer, Map<String, List<int[]>>> atomSpec;
+
+ /**
+ * Constructor
+ */
+ public AtomSpecModel()
+ {
+ atomSpec = new TreeMap<>();
+ }
+
+ public Map<Integer, Map<String, List<int[]>>> getMap()
+ {
+ return atomSpec;
+ }
+
+ /**
+ * Adds one contiguous range to this atom spec
+ *
+ * @param model
+ * @param startPos
+ * @param endPos
+ * @param chain
+ */
+ public void addRange(int model, int startPos, int endPos, String chain)
+ {
+ /*
+ * Get/initialize map of data for the colour and model
+ */
+ Map<String, List<int[]>> modelData = atomSpec.get(model);
+ if (modelData == null)
+ {
+ atomSpec.put(model, modelData = new TreeMap<>());
+ }
+
+ /*
+ * Get/initialize map of data for colour, model and chain
+ */
+ List<int[]> chainData = modelData.get(chain);
+ if (chainData == null)
+ {
+ chainData = new ArrayList<>();
+ modelData.put(chain, chainData);
+ }
+
+ /*
+ * Add the start/end positions
+ */
+ chainData.add(new int[] { startPos, endPos });
+ // TODO add intelligently, using a RangeList class
+ }
+
+ /**
+ * Answers an iterable set of the structure models in this model
+ *
+ * @return
+ */
+ public Iterable<Integer> getModels()
+ {
+ return atomSpec.keySet();
+ }
+
+ /**
+ * Answers an iterable set of the chains in this model for the given structure
+ * model, or an empty set if none
+ *
+ * @param model
+ * @return
+ */
+ public Iterable<String> getChains(Integer model)
+ {
+ if (atomSpec.containsKey(model))
+ {
+ return atomSpec.get(model).keySet();
+ }
+ return Collections.emptySet();
+ }
+
+ public List<int[]> getRanges(Integer model, String chain)
+ {
+ Map<String, List<int[]>> modelData = atomSpec.get(model);
+ if (modelData != null)
+ {
+ List<int[]> chainData = modelData.get(chain);
+ if (chainData != null)
+ {
+ return chainData;
+ }
+ }
+ return Collections.EMPTY_LIST;
+ }
+}
* </pre>
*
* @param featureMap
+ * @param binding
* @return
*/
@Override
import ext.edu.ucsf.rbvi.strucviz2.ChimeraModel;
import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
+import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
* @param pdbfnum
* @return
*/
- protected String getModelSpec(int pdbfnum)
+ @Override
+ public String getModelSpec(int pdbfnum)
{
if (pdbfnum < 0 || pdbfnum >= getPdbCount())
{
* to the Chimera command 'list models type molecule', see
* ChimeraManager.getModelList().
*/
- List<ChimeraModel> maps = chimeraMaps.get(getStructureFiles()[pdbfnum]);
+ String[] structureFiles = getStructureFiles();
+ if (pdbfnum < 0 || pdbfnum >= structureFiles.length)
+ {
+ return "";
+ }
+
+ List<ChimeraModel> maps = chimeraMaps.get(structureFiles[pdbfnum]);
boolean hasSubModels = maps != null && maps.size() > 1;
- return "#" + String.valueOf(pdbfnum) + (hasSubModels ? ".1" : "");
+ String spec = "#" + String.valueOf(pdbfnum);
+ return hasSubModels ? spec + ".1" : spec;
}
/**
public int sendFeaturesToViewer(AlignmentViewPanel avp)
{
// TODO refactor as required to pull up to an interface
-
Map<String, Map<Object, AtomSpecModel>> featureValues = buildFeaturesMap(
avp);
List<StructureCommandI> commands = getCommandGenerator()
{
return "https://www.cgl.ucsf.edu/chimera/docs/UsersGuide";
}
+
+ @Override
+ public void showStructures(AlignViewportI av, boolean refocus)
+ {
+ StructureCommandI cmd = buildShowStructuresCommand(av, refocus);
+ executeCommand(cmd, false);
+ }
+
+ /**
+ * Builds a command to show parts of the structure, depending on whether
+ * <ul>
+ * <li>all structures or regions mapped to alignment only are shown</li>
+ * <li>all chains or only selected chains are shown</li>
+ * </ul>
+ *
+ * @param av
+ * @param refocus
+ * @return
+ */
+ protected StructureCommandI buildShowStructuresCommand(
+ AlignViewportI av,
+ boolean refocus)
+ {
+ // TODO refactor using command generator
+ // pull up this method and Jmol variant to base class
+ StringBuilder cmd = new StringBuilder(128);
+ cmd.append("~display");
+
+ if (isShowAlignmentOnly())
+ {
+ AtomSpecModel model = getShownResidues(av);
+ String atomSpec = getCommandGenerator().getAtomSpec(model, false);
+ if (!atomSpec.isEmpty())
+ {
+ cmd.append("; ~ribbon; ribbon ").append(atomSpec);
+ }
+ }
+ else
+ {
+ cmd.append("; ribbon");
+ }
+
+ /*
+ * hide any chains selected not to be shown (whether mapped to
+ * sequence in the alignment or not)
+ */
+ for (String pdbChain : chainsToHide)
+ {
+ String chainId = pdbChain.split(":")[1];
+ String modelNo = getModelIdForFile(getFileForChain(pdbChain));
+ if (!"".equals(modelNo))
+ {
+ cmd.append("; ~ribbon #").append(modelNo).append(":.")
+ .append(chainId);
+ }
+ }
+ if (refocus)
+ {
+ cmd.append("; focus");
+ }
+ return new StructureCommand(cmd.toString());
+ }
+
+ @Override
+ public int getModelForPdbFile(String fileName, int fileIndex)
+ {
+ if (chimeraMaps.containsKey(fileName))
+ {
+ List<ChimeraModel> models = chimeraMaps.get(fileName);
+ if (!models.isEmpty())
+ {
+ return models.get(0).getModelNumber();
+ }
+ }
+ return -1;
+ }
}
{
@Override
- public AlignmentPanel[] getAllAlignmentPanels()
+ public AlignmentViewPanel[] getAllAlignmentPanels()
{
origview.clear();
origview.add(alignPanel);
{
if (origview.size() > 0)
{
- final AlignmentPanel ap = origview.get(0);
+ final AlignmentViewPanel avp = origview.get(0);
/*
* Copy the ViewStyle of the selected panel to 'this one'.
.getAlignViewport().getCodingComplement() != null;
if (!fromSplitFrame)
{
- vs.setScaleProteinAsCdna(ap.getAlignViewport()
+ vs.setScaleProteinAsCdna(avp.getAlignViewport()
.getViewStyle().isScaleProteinAsCdna());
}
- ap.getAlignViewport().setViewStyle(vs);
+ avp.getAlignViewport().setViewStyle(vs);
/*
* Also rescale ViewStyle of SplitFrame complement if there is
* the whole ViewStyle (allow cDNA protein to have different
* fonts)
*/
- AlignViewportI complement = ap.getAlignViewport()
+ AlignViewportI complement = avp.getAlignViewport()
.getCodingComplement();
if (complement != null && vs.isScaleProteinAsCdna())
{
af.setMenusForViewport();
}
+ avp.setSelected(true);
+ AlignmentPanel ap = (AlignmentPanel) avp;
ap.updateLayout();
- ap.setSelected(true);
ap.alignFrame.setMenusForViewport();
-
}
}
});
*/
package jalview.gui;
-import jalview.analysis.AnnotationSorter;
-import jalview.api.AlignViewportI;
-import jalview.api.AlignmentViewPanel;
-import jalview.bin.Cache;
-import jalview.bin.Jalview;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.HiddenColumns;
-import jalview.datamodel.SearchResultsI;
-import jalview.datamodel.SequenceFeature;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.gui.ImageExporter.ImageWriterI;
-import jalview.io.HTMLOutput;
-import jalview.jbgui.GAlignmentPanel;
-import jalview.math.AlignmentDimension;
-import jalview.schemes.ResidueProperties;
-import jalview.structure.StructureSelectionManager;
-import jalview.util.Comparison;
-import jalview.util.ImageMaker;
-import jalview.util.MessageManager;
-import jalview.viewmodel.ViewportListenerI;
-import jalview.viewmodel.ViewportRanges;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import javax.swing.SwingUtilities;
+import jalview.analysis.AnnotationSorter;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.SearchResultsI;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.gui.ImageExporter.ImageWriterI;
+import jalview.io.HTMLOutput;
+import jalview.jbgui.GAlignmentPanel;
+import jalview.math.AlignmentDimension;
+import jalview.schemes.ResidueProperties;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.Comparison;
+import jalview.util.ImageMaker;
+import jalview.util.MessageManager;
+import jalview.viewmodel.ViewportListenerI;
+import jalview.viewmodel.ViewportRanges;
+
/**
* DOCUMENT ME!
*
*
* @param b
*/
+ @Override
public void setSelected(boolean b)
{
try
return calculationDialog;
}
+ @Override
+ public String getTitle()
+ {
+ return alignFrame == null ? null : alignFrame.getTitle();
+ }
}
}
// refresh the sequence colours for the new structure(s)
- for (AlignmentViewPanel ap : _colourwith)
+ for (AlignmentViewPanel avp : _colourwith)
{
- jmb.updateColours(ap);
+ jmb.updateColours(avp);
}
// do superposition if asked to
if (alignAddedStructures)
super.initMenus();
savemenu.setVisible(false); // not yet implemented
- viewMenu.add(fitToWindow);
JMenuItem writeFeatures = new JMenuItem(
MessageManager.getString("label.create_viewer_attributes"));
}
// refresh the sequence colours for the new structure(s)
- for (AlignmentViewPanel ap : _colourwith)
+ for (AlignmentViewPanel avp : _colourwith)
{
- jmb.updateColours(ap);
+ jmb.updateColours(avp);
}
// do superposition if asked to
if (alignAddedStructures)
}
@Override
- protected void fitToWindow_actionPerformed()
- {
- jmb.focusView();
- }
-
- @Override
public ViewerType getViewerType()
{
return ViewerType.CHIMERA;
*/
package jalview.gui;
+import javax.swing.JComponent;
+
import jalview.api.AlignmentViewPanel;
import jalview.api.structures.JalviewStructureDisplayI;
import jalview.datamodel.PDBEntry;
import jalview.io.DataSourceType;
import jalview.structure.StructureSelectionManager;
-import javax.swing.JComponent;
-import javax.swing.SwingUtilities;
-
public class JalviewChimeraBindingModel extends JalviewChimeraBinding
{
public JalviewChimeraBindingModel(ChimeraViewFrame chimeraViewFrame,
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.Vector;
public abstract class StructureViewerBase extends GStructureViewer
implements Runnable, ViewSetProvider
{
+ private static final String UNMAPPED = "(unmapped)";
+
/*
* names for colour options (additional to Jalview colour schemes)
*/
}
@Override
- public boolean isUsedForColourBy(AlignmentViewPanel ap2)
+ public boolean isUsedForColourBy(AlignmentViewPanel avp)
{
- return (_colourwith != null) && _colourwith.contains(ap2);
+ return (_colourwith != null) && _colourwith.contains(avp);
}
/**
{
return;
}
+
+ /*
+ * add the 'All' menu item
+ */
JMenuItem menuItem = new JMenuItem(
MessageManager.getString("label.all"));
menuItem.addActionListener(new ActionListener()
allChainsSelected = false;
}
});
-
chainMenu.add(menuItem);
+ /*
+ * add a menu item for each structure and chain
+ */
+ Collections.sort(chainNames);
for (String chain : chainNames)
{
- menuItem = new JCheckBoxMenuItem(chain, true);
+ String seqName = getSequenceNameForChain(chain);
+ if (seqName == null)
+ {
+ seqName = UNMAPPED;
+ }
+ int nameLength = seqName.length();
+ if (nameLength > 16)
+ {
+ seqName = seqName.substring(0, 8) + "..."
+ + seqName.substring(nameLength - 8, nameLength);
+ }
+ String text = chain + " " + seqName;
+ menuItem = new JCheckBoxMenuItem(text, true);
menuItem.addItemListener(new ItemListener()
{
@Override
}
/**
+ * Answers the name of the sequence mapped to the given chain (formatted as
+ * pdbId:chainId, e.g. 1A70:A). Answers null if no mapped sequence is found. If
+ * more than one sequence is matched, just answers the name of the first one
+ * found.
+ *
+ * @param chain
+ * @return
+ */
+ private String getSequenceNameForChain(String chain)
+ {
+ String[] tokens = chain.split(":");
+ String pdbId = tokens[0];
+ String chainId = tokens[1];
+ List<StructureMapping> mappings = getBinding().getSsm()
+ .getMappingForChain(pdbId, chainId);
+ return mappings.isEmpty() ? null
+ : mappings.get(0).getSequence().getName();
+ }
+
+ /**
* Action on selecting one of Jalview's registered colour schemes
*/
@Override
});
viewMenu.add(seqColourBy);
+ showAlignmentOnly = new JCheckBoxMenuItem(
+ MessageManager.getString("label.show_alignment_only"));
+ showAlignmentOnly.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ hideHiddenRegions.setEnabled(showAlignmentOnly.isSelected());
+ getBinding().setShowAlignmentOnly(showAlignmentOnly.isSelected());
+ getBinding().showStructures(getAlignmentPanel().getAlignViewport(),
+ true);
+ }
+ });
+ viewMenu.add(showAlignmentOnly);
+
+ hideHiddenRegions = new JCheckBoxMenuItem(
+ MessageManager.getString("label.hide_hidden_regions"));
+ hideHiddenRegions.setEnabled(false);
+ hideHiddenRegions.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ getBinding().setHideHiddenRegions(hideHiddenRegions.isSelected());
+ getBinding().showStructures(getAlignmentPanel().getAlignViewport(),
+ false);
+ }
+ });
+ viewMenu.add(hideHiddenRegions);
+ viewMenu.add(fitToWindow);
+
final ItemListener handler = new ItemListener()
{
@Override
}
} catch (Exception e)
{
- StringBuffer sp = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (AlignmentViewPanel alignPanel : _alignwith)
{
- sp.append("'" + alignPanel.getViewName() + "' ");
+ sb.append("'").append(alignPanel.getViewName()).append("' ");
}
- Cache.log.info("Couldn't align structures with the " + sp.toString()
+ Cache.log.info("Couldn't align structures with the " + sb.toString()
+ "associated alignment panels.", e);
}
return reply;
}
}
// Set the colour using the current view for the associated alignframe
- for (AlignmentViewPanel alignPanel : _colourwith)
+ for (AlignmentViewPanel avp : _colourwith)
{
- binding.colourBySequence(alignPanel);
+ binding.updateStructureColours(avp);
}
seqColoursApplied = true;
}
}
@Override
+ public abstract AAStructureBindingModel getBinding();
+
+ /**
+ * Show only the selected chain(s) in the viewer
+ */
+ protected void showSelectedChains()
+ {
+ setChainsToHide();
+
+ /*
+ * refresh display without resizing - easier to see what changed
+ */
+ getBinding().showStructures(getAlignmentPanel().getAlignViewport(),
+ false);
+ }
+
+ @Override
public long startProgressBar(String msg)
{
// TODO would rather have startProgress/stopProgress as the
}
/**
- * 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);
- }
-
- /**
* Tries to fetch a PDB file and save to a temporary local file. Returns the
* saved file path if successful, or null if not.
*
{
public interface ViewSetProvider
{
- public AlignmentPanel[] getAllAlignmentPanels();
+ public AlignmentViewPanel[] getAllAlignmentPanels();
}
private ViewSetProvider _allviews;
private void rebuild()
{
removeAll();
- AlignmentPanel[] allviews = _allviews.getAllAlignmentPanels();
+ AlignmentViewPanel[] allviews = _allviews.getAllAlignmentPanels();
if (allviews == null)
{
setVisible(false);
invertSel.setEnabled(append);
selectAll.setEnabled(append);
}
- for (final AlignmentPanel ap : allviews)
+ for (final AlignmentViewPanel ap : allviews)
{
String nm = ((ap.getViewName() == null
|| ap.getViewName().length() == 0) ? ""
: ap.getViewName() + " for ")
- + ap.alignFrame.getTitle();
+ + ap.getTitle();
final JCheckBoxMenuItem checkBox = new JCheckBoxMenuItem(nm,
_selectedviews.contains(ap));
checkBox.addItemListener(new ItemListener()
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.JCheckBoxMenuItem;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
protected JMenuItem alignStructs;
+ protected JCheckBoxMenuItem showAlignmentOnly;
+
+ protected JCheckBoxMenuItem hideHiddenRegions;
+
protected JMenuItem fitToWindow;
protected JRadioButtonMenuItem seqColour;
@Override
public void actionPerformed(ActionEvent actionEvent)
{
- fitToWindow_actionPerformed();
+ getBinding().focusView();
}
});
statusPanel.add(statusBar, null);
}
- protected void fitToWindow_actionPerformed()
- {
- }
-
protected void highlightSelection_actionPerformed()
{
}
{
}
+
+ /**
+ * Saves the unselected entries in the 'View Chain' menu into a list. Entries
+ * are formatted as "pdbid:chainid". Unselected chains should be hidden in the
+ * structure display.
+ */
+ protected void setChainsToHide()
+ {
+ List<String> chains = new ArrayList<>();
+ for (int i = 0; i < chainMenu.getItemCount(); i++)
+ {
+ JMenuItem menuItem = chainMenu.getItem(i);
+ if (menuItem instanceof JCheckBoxMenuItem)
+ {
+ JCheckBoxMenuItem item = (JCheckBoxMenuItem) menuItem;
+ if (!item.isSelected())
+ {
+ chains.add(item.getText().split(" ")[0]);
+ }
+ }
+ }
+ getBinding().setChainsToHide(chains);
+ }
}
public abstract class StructureCommandsBase implements StructureCommandsI
{
private static final String CMD_SEPARATOR = ";";
+
public static final String NAMESPACE_PREFIX = "jv_";
/**
}
/**
+ * Answers a (possibly empty) list of structure to sequence mappings matching
+ * the given pdb and chain ids
+ *
+ * @param pdbId
+ * @param chain
+ * @return
+ */
+ public List<StructureMapping> getMappingForChain(String pdbId,
+ String chain)
+ {
+ List<StructureMapping> result = new ArrayList<>();
+ for (StructureMapping sm : mappings)
+ {
+ if (sm.pdbid.equals(pdbId) && sm.pdbchain.equals(chain))
+ {
+ result.add(sm);
+ }
+ }
+ return result;
+ }
+
+ /**
* Returns a readable description of all mappings for the given pdbfile to any
* of the given sequences
*
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
private boolean finishedInit = false;
- /**
- * current set of model filenames loaded in the viewer
+ /*
+ * current set of model filenames loaded in the Jmol instance
+ * array index 0, 1, 2... corresponds to Jmol model numbers 1, 2, 3...
*/
protected String[] modelFileNames = null;
public String fileLoadingError;
+ private boolean showAlignmentOnly;
+
+ /*
+ * a list of chains "pdbid:chainid" to hide in the viewer
+ */
+ // TODO make private once deprecated JalviewJmolBinding.centerViewer removed
+ protected List<String> chainsToHide;
+
+ private boolean hideHiddenRegions;
+
/**
* Constructor
*
{
this.ssm = ssm;
this.sequence = seqs;
+ chainsToHide = new ArrayList<>();
chainNames = new ArrayList<>();
chainFile = new HashMap<>();
}
this.nucleotide = Comparison.isNucleotide(sequenceIs);
this.pdbEntry = pdbentry;
this.protocol = protocol;
+ chainsToHide = new ArrayList<>();
+
resolveChains();
}
/**
* 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
+ * prior to matching the viewer's contents to the list of structure files
* Jalview knows about. By default does nothing, override as required.
*/
public void refreshPdbEntries()
AlignmentViewPanel alignment);
/**
+ * Recolours mapped residues in the structure viewer to match colours in the
+ * given alignment panel, provided colourBySequence is selected. Colours
+ * should also be applied to any hidden mapped residues (so that they are
+ * shown correctly if these get unhidden).
+ *
+ * @param viewPanel
+ */
+ protected void colourBySequence(AlignmentViewPanel viewPanel)
+ {
+
+ if (!colourBySequence || !isLoadingFinished() || getSsm() == null)
+ {
+ return;
+ }
+ Map<Object, AtomSpecModel> colourMap = buildColoursMap(ssm, sequence,
+ viewPanel);
+
+ List<StructureCommandI> colourBySequenceCommands = commandGenerator
+ .colourBySequence(colourMap);
+ executeCommands(colourBySequenceCommands, false, null);
+
+ }
+
+ /**
* 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);
}
}
/**
- * Colours any structures associated with sequences in the given alignment as
- * coloured in the alignment view, provided colourBySequence is enabled
+ * Recolours the displayed structures, if they are coloured by
+ * sequence, or 'show only visible alignment' is selected. This supports
+ * updating structure colours on either change of alignment colours, or change
+ * to the visible region of the alignment.
*/
- public void colourBySequence(AlignmentViewPanel alignmentv)
+ public void updateStructureColours(AlignmentViewPanel alignmentv)
{
- if (!colourBySequence || !isLoadingFinished() || getSsm() == null)
+ if (!isLoadingFinished())
{
return;
}
- Map<Object, AtomSpecModel> colourMap = buildColoursMap(ssm, sequence,
- alignmentv);
- List<StructureCommandI> colourBySequenceCommands = commandGenerator
- .colourBySequence(colourMap);
- executeCommands(colourBySequenceCommands, false, null);
+ /*
+ * if structure is not coloured by sequence, but restricted to the alignment,
+ * then redraw it (but don't recolour it) in case hidden regions have changed
+ * (todo: specific messaging for change of hidden region only)
+ */
+ if (!colourBySequence)
+ {
+ if (isShowAlignmentOnly())
+ {
+ showStructures(alignmentv.getAlignViewport(), false);
+ }
+ return;
+ }
+ if (getSsm() == null)
+ {
+ return;
+ }
+ colourBySequence(alignmentv);
}
/**
}
/**
+ * Sets the flag for whether only mapped visible residues in the alignment
+ * should be visible in the structure viewer
+ *
+ * @param b
+ */
+ public void setShowAlignmentOnly(boolean b)
+ {
+ showAlignmentOnly = b;
+ }
+
+ /**
+ * Answers true if only residues mapped to the alignment should be shown in the
+ * structure viewer, else false
+ *
+ * @return
+ */
+ public boolean isShowAlignmentOnly()
+ {
+ return showAlignmentOnly;
+ }
+
+ /**
+ * Sets the flag for hiding regions of structure which are hidden in the
+ * alignment (only applies when the structure viewer is restricted to the
+ * alignment only)
+ *
+ * @param b
+ */
+ public void setHideHiddenRegions(boolean b)
+ {
+ hideHiddenRegions = b;
+ }
+
+ /**
+ * Answers true if regions hidden in the alignment should also be hidden in the
+ * structure viewer, else false (only applies when the structure viewer is
+ * restricted to the alignment only)
+ *
+ * @return
+ */
+ public boolean isHideHiddenRegions()
+ {
+ return hideHiddenRegions;
+ }
+
+ /**
+ * Shows the structures in the viewer, without changing their colouring. This is
+ * to support toggling of whether the whole structure is shown, or only residues
+ * mapped to visible regions of the alignment.
+ *
+ * @param alignViewportI
+ * @param refocus
+ * if true, refit the display to the viewer
+ */
+ public void showStructures(AlignViewportI alignViewportI, boolean refocus)
+ {
+ // override with implementation
+ }
+
+ /**
+ * Sets the list of chains to hide (as "pdbid:chain")
+ *
+ * @param chains
+ */
+ public void setChainsToHide(List<String> chains)
+ {
+ chainsToHide = chains;
+ }
+
+ /**
+ * Answers true if the specified structure and chain are selected to be shown in
+ * the viewer, else false
+ *
+ * @param pdbId
+ * @param chainId
+ * @return
+ */
+ protected boolean isShowChain(String pdbId, String chainId)
+ {
+ if (chainsToHide.isEmpty())
+ {
+ return true;
+ }
+ return !chainsToHide.contains(pdbId + ":" + chainId);
+ }
+
+ @Override
+ public abstract String[] getStructureFiles();
+
+ /**
+ * Builds a model of residues mapped from sequences to show on structure, taking
+ * into account user choices of
+ * <ul>
+ * <li>which chains are shown</li>
+ * <li>whether all structure is shown, or only that mapped to the alignment</li>
+ * <li>whether hidden regions of the alignment are hidden (excluded) or grayed
+ * out (included)</li>
+ * </ul>
+ *
+ * @param av
+ * @return
+ */
+ protected AtomSpecModel getShownResidues(AlignViewportI av)
+ {
+ AlignmentI alignment = av.getAlignment();
+ final int width = alignment.getWidth();
+
+ String[] files = getStructureFiles();
+
+ AtomSpecModel model = new AtomSpecModel();
+
+ for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
+ {
+ String fileName = files[pdbfnum];
+ final String modelId = getModelIdForFile(files[pdbfnum]);
+ StructureMapping[] mappings = getSsm().getMapping(fileName);
+
+ /*
+ * Find the first mapped sequence (if any) for this PDB entry which is in
+ * the alignment
+ */
+ final int seqCountForPdbFile = getSequence()[pdbfnum].length;
+ for (int s = 0; s < seqCountForPdbFile; s++)
+ {
+ for (StructureMapping mapping : mappings)
+ {
+ final SequenceI theSequence = getSequence()[pdbfnum][s];
+ if (mapping.getSequence() == theSequence
+ && alignment.findIndex(theSequence) > -1)
+ {
+ String chainCd = mapping.getChain();
+ if (!isShowChain(mapping.getPdbId(), chainCd))
+ {
+ // continue;
+ }
+ Iterator<int[]> visible;
+ if (isShowAlignmentOnly() && isHideHiddenRegions())
+ {
+ visible = alignment.getHiddenColumns()
+ .getVisContigsIterator(0, width, true);
+ }
+ else
+ {
+ visible = Collections.singletonList(new int[] { 0, width })
+ .iterator();
+ }
+ while (visible.hasNext())
+ {
+ int[] visibleRegion = visible.next();
+ int seqStartPos = theSequence.findPosition(visibleRegion[0]);
+ int seqEndPos = theSequence.findPosition(visibleRegion[1]);
+ List<int[]> residueRanges = mapping
+ .getPDBResNumRanges(seqStartPos, seqEndPos);
+ if (!residueRanges.isEmpty())
+ {
+ for (int[] range : residueRanges)
+ {
+ model.addRange(modelId, range[0], range[1], chainCd);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return model;
+ }
+
+ /**
+ * Answers the structure viewer's model number for the given PDB file, or -1 if
+ * not found
+ *
+ * @param fileName
+ * @param fileIndex
+ * index of the file in the stored array of file names
+ * @return
+ */
+ public int getModelForPdbFile(String fileName, int fileIndex)
+ {
+ return fileIndex;
+ }
+
+ /**
+ * Answers a default structure model specification which is simply the string
+ * form of the model number. Override if needed to specify submodels.
+ *
+ * @param model
+ * @return
+ */
+ public String getModelSpec(int model)
+ {
+ return String.valueOf(model);
+ }
+
+ /**
* Returns the FeatureRenderer for the given alignment view, or null if
* feature display is turned off in the view.
*
}
if (!isLoadingFromArchive())
{
- colourBySequence(ap);
+ updateStructureColours(ap);
}
}
--- /dev/null
+package jalview.util;
+
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.api.FeatureRenderer;
+import jalview.api.SequenceRenderer;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.SequenceI;
+import jalview.ext.rbvi.chimera.AtomSpecModel;
+import jalview.renderer.seqfeatures.FeatureColourFinder;
+import jalview.structure.StructureMapping;
+import jalview.structures.models.AAStructureBindingModel;
+
+import java.awt.Color;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A class with common methods for building commands for Jmol, Chimera, or other
+ *
+ * @author gmcarstairs
+ */
+public abstract class StructureCommands
+{
+
+ /**
+ * 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
+ */
+ public 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);
+ }
+
+ /**
+ * Build a data structure which records contiguous subsequences by colour, model
+ * and chain. From this we can easily generate the Chimera or Jmol specific
+ * selection expression.
+ *
+ * <pre>
+ * Color
+ * Model number
+ * Chain
+ * list of start/end ranges
+ * </pre>
+ *
+ * Ordering is by order of addition (for colours and positions), natural
+ * ordering (for models and chains)
+ *
+ * @param viewPanel
+ * @return
+ */
+ public static Map<Object, AtomSpecModel> buildColoursMap(
+ AAStructureBindingModel binding, AlignmentViewPanel viewPanel)
+ {
+ FeatureRenderer fr = viewPanel.getFeatureRenderer();
+ FeatureColourFinder finder = new FeatureColourFinder(fr);
+ AlignViewportI viewport = viewPanel.getAlignViewport();
+ HiddenColumns cs = viewport.getAlignment().getHiddenColumns();
+ AlignmentI al = viewport.getAlignment();
+ SequenceRenderer sr = binding.getSequenceRenderer(viewPanel);
+ String[] files = binding.getStructureFiles();
+ SequenceI[][] sequence = binding.getSequence();
+
+ Map<Object, AtomSpecModel> colourMap = new LinkedHashMap<>();
+ Color lastColour = null;
+
+ for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
+ {
+ String fileName = files[pdbfnum];
+ final int modelNumber = binding.getModelForPdbFile(fileName, pdbfnum);
+ StructureMapping[] mapping = binding.getSsm()
+ .getMapping(fileName);
+
+ 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);
+
+ /*
+ * hidden regions are shown gray or, optionally, ignored
+ */
+ if (!cs.isVisible(r))
+ {
+ if (binding.isHideHiddenRegions())
+ {
+ continue;
+ }
+ else
+ {
+ 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)
+ {
+ StructureCommands.addAtomSpecRange(colourMap, lastColour,
+ modelNumber, startPos, lastPos, lastChain);
+ }
+ startPos = pos;
+ }
+ lastColour = colour;
+ lastPos = pos;
+ lastChain = chain;
+ }
+ // final colour range
+ if (lastColour != null)
+ {
+ StructureCommands.addAtomSpecRange(colourMap, lastColour,
+ modelNumber, startPos, lastPos, lastChain);
+ }
+ }
+ }
+ }
+ }
+ return colourMap;
+ }
+
+ /**
+ * A helper method that takes a list of [start-end] ranges, format them as
+ * s1-e1,s2-e2 etc and appends to the string buffer. Ranges are sorted, and
+ * coalesced if they overlap. The chain token, if not null, is appended to each
+ * resulting subrange.
+ *
+ * @param sb
+ * @param rangeList
+ * @param chainToken
+ * @param firstPositionForModel
+ */
+ protected static void appendResidueRange(StringBuilder sb, List<int[]> rangeList,
+ String chainToken, boolean firstPositionForModel)
+ {
+ /*
+ * sort ranges into ascending start position order
+ */
+ Collections.sort(rangeList, IntRangeComparator.ASCENDING);
+
+ int start = rangeList.isEmpty() ? 0 : rangeList.get(0)[0];
+ int end = rangeList.isEmpty() ? 0 : rangeList.get(0)[1];
+
+ Iterator<int[]> iterator = rangeList.iterator();
+ while (iterator.hasNext())
+ {
+ int[] range = iterator.next();
+ if (range[0] <= end + 1)
+ {
+ /*
+ * range overlaps or is contiguous with the last one
+ * - so just extend the end position, and carry on
+ * (unless this is the last in the list)
+ */
+ end = Math.max(end, range[1]);
+ }
+ else
+ {
+ /*
+ * we have a break so append the last range
+ */
+ appendRange(sb, start, end, chainToken, firstPositionForModel);
+ firstPositionForModel = false;
+ start = range[0];
+ end = range[1];
+ }
+ }
+
+ /*
+ * and append the last range
+ */
+ if (!rangeList.isEmpty())
+ {
+ appendRange(sb, start, end, chainToken, firstPositionForModel);
+ }
+ }
+
+ /**
+ * A helper method that appends one start-end range, and an (optional) chain
+ * token to an atomspec (a null token is not appended)
+ *
+ * @param sb
+ * @param start
+ * @param end
+ * @param chainToken
+ * @param firstPositionForModel
+ */
+ protected static void appendRange(StringBuilder sb, int start, int end,
+ String chainToken, boolean firstPositionForModel)
+ {
+ if (!firstPositionForModel)
+ {
+ sb.append(",");
+ }
+ if (end == start)
+ {
+ sb.append(start);
+ }
+ else
+ {
+ sb.append(start).append("-").append(end);
+ }
+ if (chainToken != null)
+ {
+ sb.append(chainToken);
+ }
+ }
+
+}
--- /dev/null
+package jalview.ext.jmol;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
+import jalview.gui.AppJmolBinding;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.structure.StructureMapping;
+import jalview.structure.StructureSelectionManager;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import junit.extensions.PA;
+
+public class JalviewJmolBindingTest
+{
+ private AlignFrame af;
+
+ @BeforeTest(alwaysRun = true)
+ public void setup()
+ {
+ af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
+ DataSourceType.FILE);
+ }
+
+ @Test(groups = "Functional")
+ public void testBuildShowStructuresCommand()
+ {
+ AlignViewport av = af.getViewport();
+ PDBEntry[] pdbs = new PDBEntry[] {};
+ SequenceI seq1 = av.getAlignment().findSequenceMatch("FER1_SPIOL")[0];
+ assertNotNull(seq1);
+ SequenceI seq2 = av.getAlignment().findSequenceMatch("FER2_ARATH")[0];
+ assertNotNull(seq2);
+ StructureSelectionManager ssm = new StructureSelectionManager();
+ SequenceI[][] seqs = new SequenceI[][] { { seq1 }, { seq2 } };
+ AppJmolBinding testee = new AppJmolBinding(null, ssm, pdbs, seqs,
+ null);
+
+ /*
+ * map FER1_SPIOL residues 51-100 to residues 1-50 (atoms 1-250) in 1A70
+ * and residues 110-147 to structure residues 60-97
+ * (in fact there is no gap, added here for test purposes)
+ */
+ HashMap<Integer, int[]> map = new HashMap<>();
+ for (int pos = 51; pos <= 100; pos++)
+ {
+ map.put(pos, new int[] { pos - 50, 5 * (pos - 50) });
+ }
+ for (int pos = 110; pos <= 147; pos++)
+ {
+ map.put(pos, new int[] { pos - 50, 5 * (pos - 50) });
+ }
+ StructureMapping sm1 = new StructureMapping(seq1, "1a70.pdb", "1A70",
+ "A", map, null);
+ ssm.addStructureMapping(sm1);
+
+ /*
+ * map FER2_ARATH residues 53-148 to residues 2-97 in 4ZHO
+ */
+ map = new HashMap<>();
+ for (int pos = 53; pos <= 148; pos++)
+ {
+ map.put(pos, new int[] { pos - 51, 5 * (pos - 51) });
+ }
+ StructureMapping sm2 = new StructureMapping(seq2, "4zho.pdb", "4ZHO",
+ "B", map, null);
+ ssm.addStructureMapping(sm2);
+
+ /*
+ * show everything
+ */
+ String cmd = testee.buildShowStructuresCommand(av, true);
+ assertEquals(cmd, "display *; cartoon only; zoom 0");
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd, "display *; cartoon only");
+
+ /*
+ * stub out modelFileNames - array index is Jmol
+ * model number - 1
+ */
+ PA.setValue(testee, "modelFileNames",
+ new String[]
+ { "1a70.pdb", "4zho.pdb" });
+
+ /*
+ * stub out lookup map from pdb:chain to filename
+ */
+ Map<String, String> chainFiles = new HashMap<>();
+ PA.setValue(testee, "chainFile", chainFiles);
+ chainFiles.put("1A70:A", "1a70.pdb");
+ chainFiles.put("1A70:B", "1a70.pdb");
+ chainFiles.put("4ZHO:B", "4zho.pdb");
+ chainFiles.put("4ZHO:C", "4zho.pdb");
+
+ /*
+ * show all except for selected chains to hide
+ */
+ List<String> chainsToHide = (List<String>) PA.getValue(testee,
+ "chainsToHide");
+ chainsToHide.add("1A70:B");
+ chainsToHide.add("4ZHO:C");
+ cmd = testee.buildShowStructuresCommand(av, true);
+ assertEquals(cmd,
+ "display *; hide add :B/1.1,:C/2.1; cartoon only; zoom 0");
+
+ /*
+ * show alignment only, no chains hidden
+ */
+ chainsToHide.clear();
+ testee.setShowAlignmentOnly(true);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd,
+ "hide *;display (1-50,60-97)&:A/1.1,2-97:B/2.1; select displayed; cartoon only");
+
+ /*
+ * now with a chain hidden
+ */
+ chainsToHide.add("4ZHO:C");
+ cmd = testee.buildShowStructuresCommand(av, false);
+ String expected = "hide *;display (1-50,60-97)&:A/1.1,2-97:B/2.1; select displayed; hide add :C/2.1; cartoon only";
+ assertEquals(cmd, expected);
+
+ /*
+ * hide columns in the mapped region - should not change the command (yet)
+ */
+ int fromCol = seq1.findIndex(60); // structure residue 10
+ int toCol = seq1.findIndex(70); // structure residue 20
+ av.hideColumns(fromCol - 1, toCol - 1);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd, expected);
+
+ /*
+ * select 'hide hidden columns'
+ * command should now exclude these in both mapped sequences
+ */
+ testee.setHideHiddenRegions(true);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ expected = "hide *;display (1-9,21-50,60-97)&:A/1.1,(2-10,22-97)&:B/2.1; select displayed; hide add :C/2.1; cartoon only";
+ assertEquals(cmd, expected);
+
+ /*
+ * deselect 'show alignment only'
+ * hide hidden columns is now ignored
+ */
+ testee.setShowAlignmentOnly(false);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd, "display *; hide add :C/2.1; cartoon only");
+ }
+}
testee = new JmolCommands();
}
- @Test(groups = { "Functional" })
+ /**
+ * Test for the now deprecated version of getColourBySequenceCommand
+ */
+ @Test(groups = { "Functional" }, enabled = false)
public void testGetColourBySequenceCommands_hiddenColumns()
{
/*
"B", map, null);
ssm.addStructureMapping(sm2);
- String[] commands = testee.colourBySequence(ssm,
- files,
- seqs, sr, af.alignPanel);
+ String[] commands = testee.colourBySequence(ssm, files, seqs,
+ sr,
+ af.alignPanel);
assertEquals(commands.length, 2);
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
+ 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)
chainBCommand.contains(";select 26-30:B/2.1;color[73,73,182]"));
}
- @Test(groups = "Functional")
+ @Test(groups = { "Functional" })
public void testGetAtomSpec()
{
AtomSpecModel model = new AtomSpecModel();
assertEquals(testee.getAtomSpec(model, false), "");
- model.addRange("1", 2, 4, "A");
- assertEquals(testee.getAtomSpec(model, false), "2-4:A/1.1");
- model.addRange("1", 8, 8, "A");
- assertEquals(testee.getAtomSpec(model, false), "2-4:A/1.1|8:A/1.1");
- model.addRange("1", 5, 7, "B");
- assertEquals(testee.getAtomSpec(model, false),
- "2-4:A/1.1|8:A/1.1|5-7:B/1.1");
- model.addRange("1", 3, 5, "A");
- assertEquals(testee.getAtomSpec(model, false),
- "2-5:A/1.1|8:A/1.1|5-7:B/1.1");
- model.addRange("2", 1, 4, "B");
- assertEquals(testee.getAtomSpec(model, false),
- "2-5:A/1.1|8:A/1.1|5-7:B/1.1|1-4:B/2.1");
- model.addRange("2", 5, 9, "C");
- assertEquals(testee.getAtomSpec(model, false),
- "2-5:A/1.1|8:A/1.1|5-7:B/1.1|1-4:B/2.1|5-9:C/2.1");
- model.addRange("1", 8, 10, "B");
- assertEquals(testee.getAtomSpec(model, false),
- "2-5:A/1.1|8:A/1.1|5-10:B/1.1|1-4:B/2.1|5-9:C/2.1");
- model.addRange("1", 8, 9, "B");
- assertEquals(testee.getAtomSpec(model, false),
- "2-5:A/1.1|8:A/1.1|5-10:B/1.1|1-4:B/2.1|5-9:C/2.1");
- model.addRange("2", 3, 10, "C"); // subsumes 5-9
- assertEquals(testee.getAtomSpec(model, false),
- "2-5:A/1.1|8:A/1.1|5-10:B/1.1|1-4:B/2.1|3-10:C/2.1");
- model.addRange("5", 25, 35, " ");
- assertEquals(testee.getAtomSpec(model, false),
- "2-5:A/1.1|8:A/1.1|5-10:B/1.1|1-4:B/2.1|3-10:C/2.1|25-35:/5.1");
+ /*
+ * Jalview numbers models from 0, Jmol from 1
+ */
+ model.addRange("2", 2, 4, "A");
+ assertEquals(testee.getAtomSpec(model, false), "2-4:A/2.1");
+
+ model.addRange("2", 8, 8, "A");
+ assertEquals(testee.getAtomSpec(model, false), "(2-4,8)&:A/2.1");
+
+ model.addRange("2", 5, 7, "B");
+ assertEquals(testee.getAtomSpec(model,
+ false),
+ "(2-4,8)&:A/2.1,5-7:B/2.1");
+
+ model.addRange("2", 3, 5, "A");
+ // 3-5 merges with 2-4 to make 2-5:
+ assertEquals(testee.getAtomSpec(model,
+ false),
+ "(2-5,8)&:A/2.1,5-7:B/2.1");
+
+ model.addRange("1", 1, 4, "B");
+ assertEquals(testee.getAtomSpec(model,
+ false),
+ "1-4:B/1.1,(2-5,8)&:A/2.1,5-7:B/2.1");
+
+ model.addRange("1", 5, 9, "C");
+ assertEquals(testee.getAtomSpec(model,
+ false),
+ "1-4:B/1.1,5-9:C/1.1,(2-5,8)&:A/2.1,5-7:B/2.1");
+
+ model.addRange("2", 8, 10, "B");
+ // 8-10 extends 5-7 to make 5-10
+ assertEquals(testee.getAtomSpec(model,
+ false),
+ "1-4:B/1.1,5-9:C/1.1,(2-5,8)&:A/2.1,5-10:B/2.1");
+
+ model.addRange("2", 8, 9, "B");
+ // subsumed by 5-10 so makes no difference
+ assertEquals(testee.getAtomSpec(model,
+ false),
+ "1-4:B/1.1,5-9:C/1.1,(2-5,8)&:A/2.1,5-10:B/2.1");
+
+ model.addRange("1", 3, 10, "C");
+ // subsumes 5-9 so replaces it
+ assertEquals(testee.getAtomSpec(model,
+ false),
+ "1-4:B/1.1,3-10:C/1.1,(2-5,8)&:A/2.1,5-10:B/2.1");
+
+ // empty chain code - e.g. from homology modelling
+ model.addRange("6", 25, 35, " ");
+ assertEquals(testee.getAtomSpec(model,
+ false),
+ "1-4:B/1.1,3-10:C/1.1,(2-5,8)&:A/2.1,5-10:B/2.1,25-35:/6.1");
}
@Test(groups = { "Functional" })
// they were added; within colour, by model, by chain, ranges in start order
List<StructureCommandI> commands = testee.colourBySequence(map);
assertEquals(commands.size(), 1);
- String expected1 = "select 2-5:A/1.1|9-23:A/1.1|7:B/1.1|1:A/2.1|4-7:B/2.1;color[0,0,255]";
- String expected2 = "select 3-5:A/2.1|8:A/2.1;color[255,255,0]";
+ String expected1 = "select (2-5,9-23)&:A/1.1,7:B/1.1,1:A/2.1,4-7:B/2.1;color[0,0,255]";
+ String expected2 = "select (3-5,8)&:A/2.1;color[255,255,0]";
String expected3 = "select 3-9:A/1.1;color[255,0,0]";
assertEquals(commands.get(0).getCommand(),
expected1 + ";" + expected2 + ";" + expected3);
List<StructureCommandI> command = testee.superposeStructures(ref,
toAlign);
assertEquals(command.size(), 1);
- String refSpec = "12-14:A/1.1|18:B/1.1|22-23:B/1.1";
- String toAlignSpec = "15-17:B/2.1|20-21:B/2.1|22:C/2.1";
+ String refSpec = "12-14:A/1.1,(18,22-23)&:B/1.1";
+ String toAlignSpec = "(15-17,20-21)&:B/2.1,22:C/2.1";
String expected = String.format(
"compare {2.1} {1.1} SUBSET {(*.CA | *.P) and conformation=1} ATOMS {%s}{%s} ROTATE TRANSLATE ;select %s|%s;cartoons",
toAlignSpec, refSpec, toAlignSpec, refSpec);
@Test(groups = { "Functional" })
public void testColourBySequence()
{
-
Map<Object, AtomSpecModel> map = new LinkedHashMap<>();
ChimeraCommands.addAtomSpecRange(map, Color.blue, "0", 2, 5, "A");
ChimeraCommands.addAtomSpecRange(map, Color.blue, "0", 7, 7, "B");
// 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
+ // all prefixed with #808080 to colour hidden regions (if shown) gray
List<StructureCommandI> commands = testee.colourBySequence(map);
assertEquals(commands.size(), 1);
assertEquals(commands.get(0).getCommand(),
- "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");
+ "color #808080; 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");
}
@Test(groups = { "Functional" })
model.addRange("5", 25, 35, " "); // empty chain code
assertEquals(testee.getAtomSpec(model, true),
"#0:1-4.B,3-10.C@CA&~@.B-Z&~@.2-9|#1:2-5.A,8.A,5-10.B@CA&~@.B-Z&~@.2-9|#5:25-35.@CA&~@.B-Z&~@.2-9");
-
}
@Test(groups = "Functional")
--- /dev/null
+package jalview.ext.rbvi.chimera;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import ext.edu.ucsf.rbvi.strucviz2.ChimeraModel;
+import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
+import jalview.gui.ChimeraViewFrame;
+import jalview.gui.JalviewChimeraBindingModel;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.structure.StructureCommandI;
+import jalview.structure.StructureMapping;
+import jalview.structure.StructureSelectionManager;
+import junit.extensions.PA;
+
+public class JalviewChimeraBindingTest
+{
+ private AlignFrame af;
+
+ @BeforeTest(alwaysRun = true)
+ public void setup()
+ {
+ af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
+ DataSourceType.FILE);
+ }
+
+ @Test(groups = "Functional")
+ public void testBuildShowStructuresCommand()
+ {
+ AlignViewport av = af.getViewport();
+ PDBEntry[] pdbs = new PDBEntry[] {};
+ StructureSelectionManager ssm = new StructureSelectionManager();
+ SequenceI seq1 = av.getAlignment().findSequenceMatch("FER1_SPIOL")[0];
+ assertNotNull(seq1);
+ SequenceI seq2 = av.getAlignment().findSequenceMatch("FER2_ARATH")[0];
+ assertNotNull(seq2);
+ SequenceI[][] seqs = new SequenceI[][] { { seq1 }, { seq2 } };
+ JalviewChimeraBindingModel testee = new JalviewChimeraBindingModel(
+ new ChimeraViewFrame(),
+ ssm, pdbs, seqs, null);
+
+ /*
+ * with no structures mapped
+ */
+ StructureCommandI cmd = testee.buildShowStructuresCommand(av, true);
+ assertEquals(cmd.getCommand(), "~display; ribbon; focus");
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd.getCommand(), "~display; ribbon");
+
+ /*
+ * stub out a structure with chains A and B
+ */
+ Map<String, List<ChimeraModel>> chimeraMaps = (Map<String, List<ChimeraModel>>) PA
+ .getValue(testee, "chimeraMaps");
+ ChimeraModel model0 = new ChimeraModel("1A70", ModelType.PDB_MODEL, 0,
+ 0);
+ chimeraMaps.put("1a70.pdb", Arrays.asList(model0));
+ ChimeraModel model1 = new ChimeraModel("4ZHO", ModelType.PDB_MODEL, 1,
+ 0);
+ chimeraMaps.put("4zho.pdb", Arrays.asList(model1));
+
+ Map<String, String> chainFiles = (Map<String, String>) PA
+ .getValue(testee, "chainFile");
+ chainFiles.put("1A70:A", "1a70.pdb");
+ chainFiles.put("1A70:B", "1a70.pdb");
+ chainFiles.put("4ZHO:B", "4zho.pdb");
+ chainFiles.put("4ZHO:C", "4zho.pdb");
+
+ /*
+ * map FER1_SPIOL residues 51-100 to residues 1-50 (atoms 1-250) in 1A70
+ * and residues 110-147 to structure residues 60-97
+ * (in fact there is no gap, added here for test purposes)
+ */
+ HashMap<Integer, int[]> map = new HashMap<>();
+ for (int pos = 51; pos <= 100; pos++)
+ {
+ map.put(pos, new int[] { pos - 50, 5 * (pos - 50) });
+ }
+ for (int pos = 110; pos <= 147; pos++)
+ {
+ map.put(pos, new int[] { pos - 50, 5 * (pos - 50) });
+ }
+ StructureMapping sm1 = new StructureMapping(seq1, "1a70.pdb", "1A70",
+ "A", map, null);
+ ssm.addStructureMapping(sm1);
+
+ /*
+ * map FER2_ARATH residues 53-148 to residues 2-97 in 4ZHO
+ */
+ map = new HashMap<>();
+ for (int pos = 53; pos <= 148; pos++)
+ {
+ map.put(pos, new int[] { pos - 51, 5 * (pos - 51) });
+ }
+ StructureMapping sm2 = new StructureMapping(seq2, "4zho.pdb", "4ZHO",
+ "B", map, null);
+ ssm.addStructureMapping(sm2);
+
+ /*
+ * select chain A only (hide chain B)
+ */
+ List<String> chainsToHide = (List<String>) PA.getValue(testee, "chainsToHide");
+ chainsToHide.add("1A70:B");
+ chainsToHide.add("4ZHO:C");
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd.getCommand(),
+ "~display; ribbon; ~ribbon #0:.B; ~ribbon #1:.C");
+
+ /*
+ * show alignment only, no chains hidden
+ */
+ chainsToHide.clear();
+ testee.setShowAlignmentOnly(true);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd
+ .getCommand(),
+ "~display; ~ribbon; ribbon #0:1-50.A,60-97.A|#1:2-97.B");
+
+ /*
+ * now with a chain hidden
+ */
+ chainsToHide.add("4ZHO:C");
+ cmd = testee.buildShowStructuresCommand(av, false);
+ String expected = "~display; ~ribbon; ribbon #0:1-50.A,60-97.A|#1:2-97.B; ~ribbon #1:.C";
+ assertEquals(cmd.getCommand(), expected);
+
+ /*
+ * hide columns in the mapped region - should not change the command (yet)
+ */
+ int fromCol = seq1.findIndex(60); // structure residue 10
+ int toCol = seq1.findIndex(70); // structure residue 20
+ av.hideColumns(fromCol - 1, toCol - 1);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd.getCommand(), expected);
+
+ /*
+ * select 'hide hidden columns'
+ * command should now exclude these in both mapped sequences
+ */
+ testee.setHideHiddenRegions(true);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ expected = "~display; ~ribbon; ribbon #0:1-9.A,21-50.A,60-97.A|#1:2-10.B,22-97.B; ~ribbon #1:.C";
+ assertEquals(cmd.getCommand(), expected);
+
+ /*
+ * deselect 'show alignment only'
+ * hide hidden columns is now ignored
+ */
+ testee.setShowAlignmentOnly(false);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd.getCommand(), "~display; ribbon; ~ribbon #1:.C");
+ }
+}
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
+import static org.testng.AssertJUnit.assertTrue;
import java.awt.Color;
import java.io.IOException;
// ideally, we would match on the actual data for the 'File' handle for
// pasted files,
// see JAL-623 - pasting is still not correctly handled...
- PDBEntry importedPDB = new PDBEntry("3A6S", "", Type.PDB,
- "Paste");
- AAStructureBindingModel binder = new AAStructureBindingModel(
- new StructureSelectionManager(), new PDBEntry[]
+ PDBEntry importedPDB = new PDBEntry("3A6S", "", Type.PDB, "Paste");
+ AAStructureBindingModel binder = newBindingModel(new PDBEntry[]
{ importedPDB },
new SequenceI[][]
- { importedAl.getSequencesArray() }, null)
- {
-
- @Override
- public void updateColours(Object source)
- {
- }
-
- @Override
- public void releaseReferences(Object svl)
- {
- }
-
- @Override
- public String[] getStructureFiles()
- {
- return null;
- }
-
- @Override
- public void highlightAtoms(List<AtomSpec> atoms)
- {
- }
-
- @Override
- public SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment)
- {
- return null;
- }
+ { importedAl.getSequencesArray() },
+ new StructureSelectionManager(), null);
- @Override
- protected List<String> executeCommand(StructureCommandI command,
- boolean getReply)
- {
- return null;
- }
-
- @Override
- protected String getModelIdForFile(String chainId)
- {
- return "";
- }
-
- @Override
- protected ViewerType getViewerType()
- {
- return null;
- }
- };
String[][] chains = binder.getChains();
assertFalse(chains == null || chains[0] == null,
"No chains discovered by binding");
}
@Override
+ public void setBackgroundColour(Color col)
+ {
+ }
+
+ @Override
public SequenceRenderer getSequenceRenderer(
AlignmentViewPanel avp)
{