From: gmungoc Date: Tue, 9 Jun 2020 10:19:33 +0000 (+0100) Subject: JAL-3390 unit tests and command and menu refinements X-Git-Url: http://source.jalview.org/gitweb/?p=jalview.git;a=commitdiff_plain;h=d69378a7c7a19760bcc240c8c082476fe50f99ae JAL-3390 unit tests and command and menu refinements --- diff --git a/src/jalview/datamodel/ColumnSelection.java b/src/jalview/datamodel/ColumnSelection.java index 6f14e21..bffd4a4 100644 --- a/src/jalview/datamodel/ColumnSelection.java +++ b/src/jalview/datamodel/ColumnSelection.java @@ -31,7 +31,7 @@ import java.util.regex.PatternSyntaxException; /** * Data class holding the selected columns and hidden column ranges for a view. - * Ranges are base 1. + * Column positions are base 0. */ public class ColumnSelection { diff --git a/src/jalview/ext/jmol/JalviewJmolBinding.java b/src/jalview/ext/jmol/JalviewJmolBinding.java index 09f3876..d5a0347 100644 --- a/src/jalview/ext/jmol/JalviewJmolBinding.java +++ b/src/jalview/ext/jmol/JalviewJmolBinding.java @@ -39,7 +39,6 @@ import org.jmol.api.JmolViewer; 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; @@ -51,7 +50,6 @@ import jalview.gui.StructureViewer.ViewerType; 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; @@ -1000,75 +998,6 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel showConsole(false); } - @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 - * - * - * @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. diff --git a/src/jalview/ext/jmol/JmolCommands.java b/src/jalview/ext/jmol/JmolCommands.java index 35ee8d2..1340822 100644 --- a/src/jalview/ext/jmol/JmolCommands.java +++ b/src/jalview/ext/jmol/JmolCommands.java @@ -122,31 +122,6 @@ public class JmolCommands extends StructureCommandsBase return FOCUS_VIEW; } - @Override - public List showChains(List 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 Arrays.asList(new StructureCommand(command)); - } - /** * Returns a command to superpose atoms in {@code atomSpec} to those in * {@code refAtoms}, restricted to alpha carbons only (Phosphorous for rna). @@ -483,4 +458,28 @@ public class JmolCommands extends StructureCommandsBase { return loadFile(filepath); } + + @Override + public StructureCommandI showStructures(AtomSpecModel restrictTo) + { + if (restrictTo == null) + { + return new StructureCommand("display *; cartoon only"); + } + String atomSpec = getAtomSpec(restrictTo, false); + String cmd = "display " + atomSpec + "; select displayed; cartoon only"; + return new StructureCommand(cmd); + } + + @Override + public StructureCommandI hideChain(String modelId, String chainId) + { + return new StructureCommand("hide add :" + chainId + "/" + modelId); + } + + @Override + public StructureCommandI hideAll() + { + return new StructureCommand("hide *"); + } } diff --git a/src/jalview/ext/pymol/PymolCommands.java b/src/jalview/ext/pymol/PymolCommands.java index 3493d03..ff7d0b2 100644 --- a/src/jalview/ext/pymol/PymolCommands.java +++ b/src/jalview/ext/pymol/PymolCommands.java @@ -22,6 +22,12 @@ import jalview.structure.StructureCommandsBase; */ public class PymolCommands extends StructureCommandsBase { + private static final StructureCommand SHOW_RIBBON = new StructureCommand("show", "ribbon"); + + private static final StructureCommand SHOW_CARTOON = new StructureCommand("show", "cartoon"); + + private static final StructureCommand HIDE_EVERYTHING = new StructureCommand("hide", "everything"); + private static final StructureCommand COLOUR_BY_CHAIN = new StructureCommand("spectrum", "chain"); private static final List COLOR_BY_CHARGE = new ArrayList<>(); @@ -36,8 +42,8 @@ public class PymolCommands extends StructureCommandsBase new StructureCommand("color", "blue", "resn LYS resn ARG")); COLOR_BY_CHARGE .add(new StructureCommand("color", "yellow", "resn CYS")); - SHOW_BACKBONE.add(new StructureCommand("hide", "everything")); - SHOW_BACKBONE.add(new StructureCommand("show", "ribbon")); + SHOW_BACKBONE.add(HIDE_EVERYTHING); + SHOW_BACKBONE.add(SHOW_RIBBON); } @Override @@ -80,22 +86,6 @@ public class PymolCommands extends StructureCommandsBase } @Override - public List showChains(List toShow) - { - // https://pymolwiki.org/index.php/Show - List commands = new ArrayList<>(); - commands.add(new StructureCommand("hide", "everything")); - commands.add(new StructureCommand("show", "lines")); - StringBuilder chains = new StringBuilder(); - for (String chain : toShow) - { - chains.append(" chain ").append(chain); - } - commands.add(new StructureCommand("show", "cartoon", chains.toString())); - return commands; - } - - @Override public List superposeStructures(AtomSpecModel refAtoms, AtomSpecModel atomSpec) { @@ -317,4 +307,30 @@ public class PymolCommands extends StructureCommandsBase return new StructureCommand("load", filepath, "", "0", "pse"); } + @Override + public StructureCommandI showStructures(AtomSpecModel restrictTo) + { + if (restrictTo == null) + { + return SHOW_CARTOON; + } + else + { + return new StructureCommand("show", "cartoon", + getAtomSpec(restrictTo, false)); + } + } + + @Override + public StructureCommandI hideChain(String modelId, String chainId) + { + return new StructureCommand("hide", modelId + "//" + chainId + "//"); + } + + @Override + public StructureCommandI hideAll() + { + return HIDE_EVERYTHING; + } + } diff --git a/src/jalview/ext/rbvi/chimera/ChimeraCommands.java b/src/jalview/ext/rbvi/chimera/ChimeraCommands.java index 642035f..8c6bafb 100644 --- a/src/jalview/ext/rbvi/chimera/ChimeraCommands.java +++ b/src/jalview/ext/rbvi/chimera/ChimeraCommands.java @@ -36,6 +36,7 @@ import jalview.util.ColorUtils; * Routines for generating Chimera commands for Jalview/Chimera binding * * @author JimP + * @see https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/framecommand.html * */ public class ChimeraCommands extends StructureCommandsBase @@ -205,41 +206,6 @@ public class ChimeraCommands extends StructureCommandsBase } @Override - public List showChains(List 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 Arrays.asList(new StructureCommand(command)); - } - - @Override public List superposeStructures(AtomSpecModel ref, AtomSpecModel spec) { @@ -407,4 +373,30 @@ public class ChimeraCommands extends StructureCommandsBase return new StructureCommand("open chimera:" + filepath); } + @Override + public StructureCommandI showStructures(AtomSpecModel restrictTo) + { + if (restrictTo == null) + { + return new StructureCommand("ribbon"); + } + + String atomSpec = getAtomSpec(restrictTo, false); + String cmd = "ribbon " + atomSpec; + return new StructureCommand(cmd); + } + + @Override + public StructureCommandI hideChain(String modelId, String chainId) + { + String cmd = "~ribbon #" + modelId + ":." + chainId; + return new StructureCommand(cmd); + } + + @Override + public StructureCommandI hideAll() + { + return new StructureCommand("~display; ~ribbon"); + } + } diff --git a/src/jalview/ext/rbvi/chimera/ChimeraXCommands.java b/src/jalview/ext/rbvi/chimera/ChimeraXCommands.java index 8a4a299..dee6e49 100644 --- a/src/jalview/ext/rbvi/chimera/ChimeraXCommands.java +++ b/src/jalview/ext/rbvi/chimera/ChimeraXCommands.java @@ -27,7 +27,6 @@ import java.util.List; import jalview.structure.AtomSpecModel; import jalview.structure.StructureCommand; import jalview.structure.StructureCommandI; -import jalview.util.ColorUtils; /** * Routines for generating ChimeraX commands for Jalview/ChimeraX binding @@ -212,4 +211,11 @@ public class ChimeraXCommands extends ChimeraCommands // this version of the command has no dependency on file extension return new StructureCommand("open " + filepath + " format session"); } + + @Override + public StructureCommandI hideChain(String modelId, String chainId) + { + String cmd = "~ribbon #" + modelId + "/" + chainId; + return new StructureCommand(cmd); + } } diff --git a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java index 0907695..718db79 100644 --- a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java +++ b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java @@ -36,7 +36,6 @@ import ext.edu.ucsf.rbvi.strucviz2.ChimeraManager; 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; @@ -832,68 +831,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel } @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 - *
    - *
  • all structures or regions mapped to alignment only are shown
  • - *
  • all chains or only selected chains are shown
  • - *
- * - * @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)) diff --git a/src/jalview/gui/PymolViewer.java b/src/jalview/gui/PymolViewer.java index c5a4c9a..8a4ce08 100644 --- a/src/jalview/gui/PymolViewer.java +++ b/src/jalview/gui/PymolViewer.java @@ -250,7 +250,7 @@ public class PymolViewer extends StructureViewerBase } catch (Exception ex) { Cache.log.error( - "Couldn't open " + pe.getFile() + " in Chimera viewer!", + "Couldn't open " + pe.getFile() + " in Pymol viewer!", ex); } finally { diff --git a/src/jalview/gui/StructureViewerBase.java b/src/jalview/gui/StructureViewerBase.java index 900252a..77ba38d 100644 --- a/src/jalview/gui/StructureViewerBase.java +++ b/src/jalview/gui/StructureViewerBase.java @@ -513,6 +513,10 @@ public abstract class StructureViewerBase extends GStructureViewer return true; } + /** + * Add menu items to the 'Show Chains' sub-menu, given a list of values formatted as "pdbId:chainCode" + * @param chainNames + */ void setChainMenuItems(List chainNames) { chainMenu.removeAll(); @@ -549,10 +553,15 @@ public abstract class StructureViewerBase extends GStructureViewer * add a menu item for each structure and chain */ Collections.sort(chainNames); + boolean hideUnmapped = getBinding().isShowAlignmentOnly(); for (String chain : chainNames) { + String[] tokens = chain.split(":"); + String pdbId = tokens[0]; + String chainCode = tokens[1]; String seqName = getSequenceNameForChain(chain); - if (seqName == null) + boolean isUnmapped = seqName == null; + if (isUnmapped) { seqName = UNMAPPED; } @@ -564,6 +573,15 @@ public abstract class StructureViewerBase extends GStructureViewer } String text = chain + " " + seqName; menuItem = new JCheckBoxMenuItem(text, true); + + /* + * set the item's state _before_ adding its listener! + */ + menuItem.setSelected(getBinding().isShowChain(pdbId, chainCode)); + if (hideUnmapped && isUnmapped) + { + menuItem.setEnabled(false); + } menuItem.addItemListener(new ItemListener() { @Override @@ -575,7 +593,6 @@ public abstract class StructureViewerBase extends GStructureViewer } } }); - chainMenu.add(menuItem); } } @@ -767,6 +784,7 @@ public abstract class StructureViewerBase extends GStructureViewer getBinding().setShowAlignmentOnly(showAlignmentOnly.isSelected()); getBinding().showStructures(getAlignmentPanel().getAlignViewport(), true); + updateTitleAndMenus(); // to add or remove unmapped chain menu items } }); viewMenu.add(showAlignmentOnly); diff --git a/src/jalview/structure/StructureCommandsI.java b/src/jalview/structure/StructureCommandsI.java index 2169184..2c3d061 100644 --- a/src/jalview/structure/StructureCommandsI.java +++ b/src/jalview/structure/StructureCommandsI.java @@ -70,15 +70,6 @@ public interface StructureCommandsI StructureCommandI focusView(); /** - * Returns a command to show only the selected chains. The items in the input - * list should be formatted as "modelid:chainid". - * - * @param toShow - * @return - */ - List showChains(List toShow); - - /** * Returns a command to superpose structures by closest positioning of * residues in {@code atomSpec} to the corresponding residues in * {@code refAtoms}. If wanted, this may include commands to visually @@ -156,4 +147,30 @@ public interface StructureCommandsI * @return */ StructureCommandI openSession(String filepath); + + /** + * Returns a command to show structures in the viewer. If {@code restrictTo} + * is null, all structures are included, otherwise the display is restricted + * to positions represented in the model + * + * @param restrictTo + * @return + */ + StructureCommandI showStructures(AtomSpecModel restrictTo); + + /** + * Returns a command to hide the specified model chain in the structure viewer + * + * @param modelId + * @param chainId + * @return + */ + StructureCommandI hideChain(String modelId, String chainId); + + /** + * Returns a command to hide everything in the structure viewer + * + * @return + */ + StructureCommandI hideAll(); } diff --git a/src/jalview/structures/models/AAStructureBindingModel.java b/src/jalview/structures/models/AAStructureBindingModel.java index 7b1485c..b23424c 100644 --- a/src/jalview/structures/models/AAStructureBindingModel.java +++ b/src/jalview/structures/models/AAStructureBindingModel.java @@ -420,6 +420,7 @@ public abstract class AAStructureBindingModel */ public void refreshGUI() { + getViewer().updateTitleAndMenus(); } /** @@ -1089,6 +1090,10 @@ public abstract class AAStructureBindingModel private List executeCommand(StructureCommandI cmd, boolean getReply, String msg) { + if (cmd == null) + { + return null; // catch unimplemented commands + } if (getReply) { /* @@ -1244,36 +1249,6 @@ public abstract class AAStructureBindingModel } /** - * 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 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 showThese = new ArrayList<>(); - for (String chainId : toShow) - { - String[] tokens = chainId.split("\\:"); - if (tokens.length == 2) - { - String pdbFile = getFileForChain(chainId); - String model = getModelIdForFile(pdbFile); - showThese.add(model + ":" + tokens[1]); - } - } - executeCommands(commandGenerator.showChains(showThese), false, null); - } - - /** * Answers the structure viewer's model id given a PDB file name. Returns an * empty string if model id is not found. * @@ -1334,17 +1309,47 @@ public abstract class AAStructureBindingModel } /** - * 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. + * 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, and/or only selected + * chains. * - * @param alignViewportI + * @param av * @param refocus - * if true, refit the display to the viewer + * if true, rescale the display to the viewer */ - public void showStructures(AlignViewportI alignViewportI, boolean refocus) + public void showStructures(AlignViewportI av, boolean refocus) { - // override with implementation + if (isShowAlignmentOnly()) + { + StructureCommandI cmd = getCommandGenerator().hideAll(); + executeCommand(cmd, false); + } + + AtomSpecModel model = isShowAlignmentOnly() ? getShownResidues(av) + : null; + StructureCommandI cmd = getCommandGenerator().showStructures(model); + executeCommand(cmd, false); + + /* + * and hide any chains selected _not_ to be shown + * (whether mapped to sequence in the alignment or not) + */ + for (String pdbChain : chainsToHide) + { + String modelNo = getModelIdForFile(getFileForChain(pdbChain)); + if (!"".equals(modelNo)) + { + String chainId = pdbChain.split(":")[1]; + cmd = getCommandGenerator().hideChain(modelNo, chainId); + executeCommand(cmd, false); + } + } + + if (refocus) + { + focusView(); + } } /** @@ -1365,7 +1370,7 @@ public abstract class AAStructureBindingModel * @param chainId * @return */ - protected boolean isShowChain(String pdbId, String chainId) + public boolean isShowChain(String pdbId, String chainId) { if (chainsToHide.isEmpty()) { @@ -1378,13 +1383,12 @@ public abstract class AAStructureBindingModel public abstract String[] getStructureFiles(); /** - * Builds a model of residues mapped from sequences to show on structure, taking - * into account user choices of + * Builds a model of residues mapped from sequences to show on structure, + * taking into account user choices of *
    + *
  • whether hidden regions of the alignment are excluded (hidden) or + * included (greyed out)
  • *
  • which chains are shown
  • - *
  • whether all structure is shown, or only that mapped to the alignment
  • - *
  • whether hidden regions of the alignment are hidden (excluded) or grayed - * out (included)
  • *
* * @param av @@ -1392,6 +1396,13 @@ public abstract class AAStructureBindingModel */ protected AtomSpecModel getShownResidues(AlignViewportI av) { + if (!isShowAlignmentOnly()) + { + Cache.log.error( + "getShownResidues only valid for 'show alignment only')"); + return null; + } + AlignmentI alignment = av.getAlignment(); final int width = alignment.getWidth(); @@ -1421,16 +1432,26 @@ public abstract class AAStructureBindingModel String chainCd = mapping.getChain(); if (!isShowChain(mapping.getPdbId(), chainCd)) { - // continue; + /* + * chain is not selected to be displayed, so don't + * waste effort computing its structure positions + */ + continue; } Iterator visible; - if (isShowAlignmentOnly() && isHideHiddenRegions()) + if (isHideHiddenRegions()) { + /* + * traverse visible columns of the alignment only + */ visible = alignment.getHiddenColumns() .getVisContigsIterator(0, width, true); } else { + /* + * traverse all columns (including hidden if any) + */ visible = Collections.singletonList(new int[] { 0, width }) .iterator(); } diff --git a/test/jalview/ext/jmol/JalviewJmolBindingTest.java b/test/jalview/ext/jmol/JalviewJmolBindingTest.java deleted file mode 100644 index 0a0b634..0000000 --- a/test/jalview/ext/jmol/JalviewJmolBindingTest.java +++ /dev/null @@ -1,160 +0,0 @@ -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 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 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 chainsToHide = (List) 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"); - } -} diff --git a/test/jalview/ext/jmol/JmolCommandsTest.java b/test/jalview/ext/jmol/JmolCommandsTest.java index cbb9e10..95b7e51 100644 --- a/test/jalview/ext/jmol/JmolCommandsTest.java +++ b/test/jalview/ext/jmol/JmolCommandsTest.java @@ -304,4 +304,39 @@ public class JmolCommandsTest cmd = testee.openSession("\\some\\filepath"); assertEquals(cmd.getCommand(), "load FILES \"\\\\some\\\\filepath\""); } + + @Test(groups = "Functional") + public void testHideAll() + { + StructureCommandI cmd = testee.hideAll(); + assertEquals(cmd.getCommand(), "hide *"); + } + + @Test(groups = "Functional") + public void testHideChain() + { + StructureCommandI cmd = testee.hideChain("1.1", "B"); + assertEquals(cmd.getCommand(), "hide add :B/1.1"); + } + + @Test(groups = "Functional") + public void testShowStructures() + { + /* + * with nothing excluded + */ + StructureCommandI cmd = testee.showStructures(null); + assertEquals(cmd.getCommand(), "display *; cartoon only"); + + /* + * restricted to specified positions + */ + AtomSpecModel restrictTo = new AtomSpecModel(); + restrictTo.addRange("1.1", 12, 20, "A"); + restrictTo.addRange("1.1", 30, 35, "A"); + restrictTo.addRange("2.1", 11, 30, "B"); + cmd = testee.showStructures(restrictTo); + assertEquals(cmd.getCommand(), + "display (12-20,30-35)&:A/1.1.1,11-30:B/2.1.1; select displayed; cartoon only"); + } } diff --git a/test/jalview/ext/pymol/PymolCommandsTest.java b/test/jalview/ext/pymol/PymolCommandsTest.java index 90d0cc7..8beee96 100644 --- a/test/jalview/ext/pymol/PymolCommandsTest.java +++ b/test/jalview/ext/pymol/PymolCommandsTest.java @@ -335,4 +335,39 @@ public class PymolCommandsTest "p.jv_side_chain_binding_='metal 'ion!'"); assertEquals(commands.get(0), expected3); } + + @Test(groups = "Functional") + public void testHideAll() + { + StructureCommandI cmd = testee.hideAll(); + assertEquals(cmd, new StructureCommand("hide", "everything")); + } + + @Test(groups = "Functional") + public void testHideChain() + { + StructureCommandI cmd = testee.hideChain("1.1", "B"); + assertEquals(cmd, new StructureCommand("hide", "1.1//B//")); + } + + @Test(groups = "Functional") + public void testShowStructures() + { + /* + * with nothing excluded + */ + StructureCommandI cmd = testee.showStructures(null); + assertEquals(cmd, new StructureCommand("show", "cartoon")); + + /* + * restricted to specified positions + */ + AtomSpecModel restrictTo = new AtomSpecModel(); + restrictTo.addRange("1.1", 12, 20, "A"); + restrictTo.addRange("1.1", 30, 35, "A"); + restrictTo.addRange("2.1", 11, 30, "B"); + cmd = testee.showStructures(restrictTo); + assertEquals(cmd, new StructureCommand("show", "cartoon", + "1.1//A/12-20+30-35/ 2.1//B/11-30/")); + } } diff --git a/test/jalview/ext/rbvi/chimera/ChimeraCommandsTest.java b/test/jalview/ext/rbvi/chimera/ChimeraCommandsTest.java index b8ca2dd..fd4ec69 100644 --- a/test/jalview/ext/rbvi/chimera/ChimeraCommandsTest.java +++ b/test/jalview/ext/rbvi/chimera/ChimeraCommandsTest.java @@ -61,11 +61,10 @@ public class ChimeraCommandsTest // 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 commands = testee.colourBySequence(map); assertEquals(commands.size(), 1); assertEquals(commands.get(0).getCommand(), - "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"); + "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" }) @@ -340,4 +339,39 @@ public class ChimeraCommandsTest assertEquals(testee.setAttribute("jv_kd", "27.3", model).getCommand(), "setattr res jv_kd '27.3' #1:89-92.A|#2:8-9.B,12-20.B"); } + + @Test(groups = "Functional") + public void testHideAll() + { + StructureCommandI cmd = testee.hideAll(); + assertEquals(cmd.getCommand(), "~display all; ~ribbon"); + } + + @Test(groups = "Functional") + public void testHideChain() + { + StructureCommandI cmd = testee.hideChain("1.1", "B"); + assertEquals(cmd.getCommand(), "~ribbon #1.1:.B"); + } + + @Test(groups = "Functional") + public void testShowStructures() + { + /* + * with nothing excluded + */ + StructureCommandI cmd = testee.showStructures(null); + assertEquals(cmd.getCommand(), "ribbon"); + + /* + * restricted to specified positions + */ + AtomSpecModel restrictTo = new AtomSpecModel(); + restrictTo.addRange("1.1", 12, 20, "A"); + restrictTo.addRange("1.1", 30, 35, "A"); + restrictTo.addRange("2.1", 11, 30, "B"); + cmd = testee.showStructures(restrictTo); + assertEquals(cmd.getCommand(), + "ribbon #1.1:12-20.A,30-35.A|#2.1:11-30.B"); + } } diff --git a/test/jalview/ext/rbvi/chimera/ChimeraXCommandsTest.java b/test/jalview/ext/rbvi/chimera/ChimeraXCommandsTest.java index 02a9dd5..16ee0b1 100644 --- a/test/jalview/ext/rbvi/chimera/ChimeraXCommandsTest.java +++ b/test/jalview/ext/rbvi/chimera/ChimeraXCommandsTest.java @@ -316,4 +316,39 @@ public class ChimeraXCommandsTest .getCommand(), "setattr #1/A:89-92|#2/B:8-9,12-20 res jv_kd '27.3' create true"); } + + @Test(groups = "Functional") + public void testHideAll() + { + StructureCommandI cmd = testee.hideAll(); + assertEquals(cmd.getCommand(), "~display all; ~ribbon"); + } + + @Test(groups = "Functional") + public void testHideChain() + { + StructureCommandI cmd = testee.hideChain("1.1", "B"); + assertEquals(cmd.getCommand(), "~ribbon #1.1/B"); + } + + @Test(groups = "Functional") + public void testShowStructures() + { + /* + * with nothing excluded + */ + StructureCommandI cmd = testee.showStructures(null); + assertEquals(cmd.getCommand(), "ribbon"); + + /* + * restricted to specified positions + */ + AtomSpecModel restrictTo = new AtomSpecModel(); + restrictTo.addRange("1.1", 12, 20, "A"); + restrictTo.addRange("1.1", 30, 35, "A"); + restrictTo.addRange("2.1", 11, 30, "B"); + cmd = testee.showStructures(restrictTo); + assertEquals(cmd.getCommand(), + "ribbon #1.1/A:12-20,30-35|#2.1/B:11-30"); + } } diff --git a/test/jalview/ext/rbvi/chimera/JalviewChimeraBindingTest.java b/test/jalview/ext/rbvi/chimera/JalviewChimeraBindingTest.java deleted file mode 100644 index fde4bb5..0000000 --- a/test/jalview/ext/rbvi/chimera/JalviewChimeraBindingTest.java +++ /dev/null @@ -1,166 +0,0 @@ -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> chimeraMaps = (Map>) 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 chainFiles = (Map) 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 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 chainsToHide = (List) 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"); - } -} diff --git a/test/jalview/structures/models/AAStructureBindingModelTest.java b/test/jalview/structures/models/AAStructureBindingModelTest.java index aea12b4..66d133c 100644 --- a/test/jalview/structures/models/AAStructureBindingModelTest.java +++ b/test/jalview/structures/models/AAStructureBindingModelTest.java @@ -126,7 +126,7 @@ public class AAStructureBindingModelTest // TODO: JAL-2227 - import mmCIF PISA assembly & identify master/copy chains - @Test(groups= {"Functional"}) + @Test(groups = { "Functional" }) public void testImportPDBPreservesChainMappings() throws IOException { AlignmentI importedAl = new jalview.io.FormatAdapter().readFile( @@ -136,7 +136,8 @@ public class AAStructureBindingModelTest // pasted files, // see JAL-623 - pasting is still not correctly handled... PDBEntry importedPDB = new PDBEntry("3A6S", "", Type.PDB, "Paste"); - AAStructureBindingModel binder = newBindingModel(new PDBEntry[] + AAStructureBindingModel binder = newBindingModel( + new PDBEntry[] { importedPDB }, new SequenceI[][] { importedAl.getSequencesArray() }, @@ -149,6 +150,7 @@ public class AAStructureBindingModelTest assertEquals(chains[0][0], "A"); assertEquals(chains[0][1], "B"); } + AAStructureBindingModel testee; AlignmentI al = null; @@ -195,11 +197,11 @@ public class AAStructureBindingModelTest * @param pdbFiles * @param seqs * @param ssm - * @param alignPanel + * @param alignPanel */ protected AAStructureBindingModel newBindingModel(PDBEntry[] pdbFiles, - SequenceI[][] seqs, - StructureSelectionManager ssm, AlignmentViewPanel avp) + SequenceI[][] seqs, StructureSelectionManager ssm, + AlignmentViewPanel avp) { AAStructureBindingModel model = new AAStructureBindingModel(ssm, pdbFiles, seqs, null) @@ -236,12 +238,10 @@ public class AAStructureBindingModelTest } @Override - public SequenceRenderer getSequenceRenderer( - AlignmentViewPanel avp) + public SequenceRenderer getSequenceRenderer(AlignmentViewPanel avp) { return avp == null ? null - : new jalview.gui.SequenceRenderer( - avp.getAlignViewport()); + : new jalview.gui.SequenceRenderer(avp.getAlignViewport()); } @Override @@ -288,10 +288,12 @@ public class AAStructureBindingModelTest /* * create a data bean to hold data per structure file */ - AAStructureBindingModel.SuperposeData[] structs = new AAStructureBindingModel.SuperposeData[testee.getStructureFiles().length]; + AAStructureBindingModel.SuperposeData[] structs = new AAStructureBindingModel.SuperposeData[testee + .getStructureFiles().length]; for (int i = 0; i < structs.length; i++) { - structs[i] = new AAStructureBindingModel.SuperposeData(al.getWidth(), "0"); + structs[i] = new AAStructureBindingModel.SuperposeData(al.getWidth(), + "0"); } /* * initialise BitSet of 'superposable columns' to true (would be false for @@ -303,8 +305,8 @@ public class AAStructureBindingModelTest matched.set(i); } - int refStructure = testee - .findSuperposableResidues(al, matched, structs); + int refStructure = testee.findSuperposableResidues(al, matched, + structs); assertEquals(refStructure, 0); @@ -336,10 +338,12 @@ public class AAStructureBindingModelTest @Test(groups = { "Functional" }) public void testFindSuperposableResidues_hiddenColumn() { - AAStructureBindingModel.SuperposeData[] structs = new AAStructureBindingModel.SuperposeData[al.getHeight()]; + AAStructureBindingModel.SuperposeData[] structs = new AAStructureBindingModel.SuperposeData[al + .getHeight()]; for (int i = 0; i < structs.length; i++) { - structs[i] = new AAStructureBindingModel.SuperposeData(al.getWidth(), "0"); + structs[i] = new AAStructureBindingModel.SuperposeData(al.getWidth(), + "0"); } /* * initialise BitSet of 'superposable columns' to true (would be false for @@ -354,8 +358,8 @@ public class AAStructureBindingModelTest // treat column 5 of the alignment as hidden matched.clear(4); - int refStructure = testee - .findSuperposableResidues(al, matched, structs); + int refStructure = testee.findSuperposableResidues(al, matched, + structs); assertEquals(refStructure, 0); @@ -393,7 +397,7 @@ public class AAStructureBindingModelTest pdbFiles[0] = new PDBEntry("PDB1", "A", Type.PDB, "seq1.pdb"); pdbFiles[1] = new PDBEntry("PDB2", "B", Type.PDB, "seq2.pdb"); StructureSelectionManager ssm = new StructureSelectionManager(); - + /* * map residues 1-10 to residues 21-30 (atoms 105-150) in structures */ @@ -419,7 +423,7 @@ public class AAStructureBindingModelTest Map colours = binding.buildColoursMap(ssm, seqs, af.alignPanel); ChimeraCommands helper = new ChimeraCommands(); - + /* * M colour is #82827d (see strand.html help page) * sequence residue 1 mapped to structure residue 21 @@ -452,7 +456,8 @@ public class AAStructureBindingModelTest Color gray = new Color(128, 128, 128); atomSpec = colours.get(gray); assertNotNull(atomSpec); - assertEquals(helper.getAtomSpec(atomSpec, false), "#0:23-25.A|#1:23-25.B"); + assertEquals(helper.getAtomSpec(atomSpec, false), + "#0:23-25.A|#1:23-25.B"); /* * S and G are both coloured #4949b6, structure residues 26-30 @@ -463,4 +468,96 @@ public class AAStructureBindingModelTest assertEquals(helper.getAtomSpec(atomSpec, false), "#0:26-30.A|#1:26-30.B"); } + + @Test(groups = { "Functional" }) + public void testGetShownResidues() + { + /* + * load these sequences, with columns 2-4 (third, fourth, fifth) hidden + */ + String fasta = ">seq1/12-21\nMHRSQSSSGG\n>seq2/12-21\nMVRSNGGSSS"; + AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(fasta, + DataSourceType.PASTE); + AlignmentI al = af.getViewport().getAlignment(); + ColumnSelection cs = new ColumnSelection(); + cs.addElement(2); + cs.addElement(3); + cs.addElement(4); + af.getViewport().setColumnSelection(cs); + af.hideSelColumns_actionPerformed(null); + SequenceI seq1 = al.getSequenceAt(0); + SequenceI seq2 = al.getSequenceAt(1); + SequenceI[][] seqs = new SequenceI[][] { { seq1 }, { seq2 } }; + PDBEntry[] pdbFiles = new PDBEntry[2]; + pdbFiles[0] = new PDBEntry("PDB1", "A", Type.PDB, "seq1.pdb"); + pdbFiles[1] = new PDBEntry("PDB2", "B", Type.PDB, "seq2.pdb"); + StructureSelectionManager ssm = new StructureSelectionManager(); + + /* + * map residues 12-21 to residues 21-30 (atoms 105-150) in structures + */ + HashMap map = new HashMap<>(); + for (int pos = 1; pos <= seq1.getLength(); pos++) + { + map.put(pos + 11, new int[] { 20 + pos, 5 * (20 + pos) }); + } + StructureMapping sm1 = new StructureMapping(seq1, "seq1.pdb", "pdb1", + "A", map, null); + ssm.addStructureMapping(sm1); + StructureMapping sm2 = new StructureMapping(seq2, "seq2.pdb", "pdb2", + "B", map, null); + ssm.addStructureMapping(sm2); + + AAStructureBindingModel binding = newBindingModel(pdbFiles, seqs, ssm, + af.alignPanel); + + /* + * with hidden columns shown on structure + */ + binding.setShowAlignmentOnly(true); + AtomSpecModel model = binding.getShownResidues(af.getViewport()); + assertEquals(model.getModelCount(), 2); + int modelNo = 0; + for (String modelId : model.getModels()) + { + assertEquals(modelId, String.valueOf(modelNo)); + Iterable chains = model.getChains(modelId); + String expectedChain = (modelNo == 0) ? "A" : "B"; + for (String chain : chains) + { + assertEquals(chain, expectedChain); + List ranges = model.getRanges(modelId, chain); + assertEquals(ranges.size(), 1); + assertEquals(ranges.get(0)[0], 21); + assertEquals(ranges.get(0)[1], 30); + } + modelNo++; + } + + /* + * with hidden columns hidden on structure + * columns 2-4 correspond to residues 23-25 on structure - now omitted + */ + binding.setHideHiddenRegions(true); + model = binding.getShownResidues(af.getViewport()); + assertEquals(model.getModelCount(), 2); + modelNo = 0; + for (String modelId : model.getModels()) + { + assertEquals(modelId, String.valueOf(modelNo)); + Iterable chains = model.getChains(modelId); + String expectedChain = (modelNo == 0) ? "A" : "B"; + for (String chain : chains) + { + assertEquals(chain, expectedChain); + List ranges = model.getRanges(modelId, chain); + assertEquals(ranges.size(), 2); + assertEquals(ranges.get(0)[0], 21); + assertEquals(ranges.get(0)[1], 22); + assertEquals(ranges.get(1)[0], 26); + assertEquals(ranges.get(1)[1], 30); + } + modelNo++; + } + } } \ No newline at end of file