From: gmungoc Date: Wed, 7 Aug 2019 13:19:17 +0000 (+0100) Subject: Merge branch 'develop' into feature/JAL-3390hideUnmappedStructure X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=5c6564f903f75960af960720a8635ab8709afc37;p=jalview.git Merge branch 'develop' into feature/JAL-3390hideUnmappedStructure Conflicts: resources/lang/Messages.properties resources/lang/Messages_es.properties src/jalview/ext/rbvi/chimera/ChimeraCommands.java test/jalview/ext/rbvi/chimera/ChimeraCommandsTest.java --- 5c6564f903f75960af960720a8635ab8709afc37 diff --cc gradle.properties index 2dbdad3,2dbdad3..f6e9bca --- a/gradle.properties +++ b/gradle.properties @@@ -1,7 -1,7 +1,7 @@@ jalviewDir = . --#JAVA_VERSION = 1.8 --JAVA_VERSION = 11 ++JAVA_VERSION = 1.8 ++#JAVA_VERSION = 11 JALVIEW_VERSION = DEVELOPMENT INSTALLATION = Source jalview_keystore = keys/.keystore diff --cc resources/lang/Messages.properties index c54e414,fdd15cd..966157c --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@@ -1400,5 -1400,7 +1400,9 @@@ label.pca = PC 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.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.include_linked_tooltip = Include visible {0} features
converted to local sequence coordinates ++label.include_linked_tooltip = Include visible {0} features
converted to local sequence coordinates diff --cc resources/lang/Messages_es.properties index a99d3bb,daa4418..8ff4bf3 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@@ -1402,5 -1401,7 +1402,9 @@@ label.pca = AC 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.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} -label.include_linked_tooltip = Incluir características de {0}
convertidas a coordenadas de secuencia local ++label.include_linked_tooltip = Incluir características de {0}
convertidas a coordenadas de secuencia local diff --cc src/jalview/ext/rbvi/chimera/ChimeraCommands.java index a6a72e0,3caaac3..45b22f7 --- a/src/jalview/ext/rbvi/chimera/ChimeraCommands.java +++ b/src/jalview/ext/rbvi/chimera/ChimeraCommands.java @@@ -254,8 -298,8 +261,8 @@@ public class ChimeraCommand * @param endPos * @param chain */ - public static void addMapRange(Map map, - Object key, int model, int startPos, int endPos, String chain) - protected static void addAtomSpecRange(Map map, ++ public static void addAtomSpecRange(Map map, + Object value, int model, int startPos, int endPos, String chain) { /* * Get/initialize map of data for the colour diff --cc src/jalview/structures/models/AAStructureBindingModel.java index 8eea16f,2528286..47e7f30 --- a/src/jalview/structures/models/AAStructureBindingModel.java +++ b/src/jalview/structures/models/AAStructureBindingModel.java @@@ -858,320 -823,4 +858,321 @@@ public abstract class AAStructureBindin public abstract jalview.api.FeatureRenderer getFeatureRenderer( AlignmentViewPanel alignment); + + /** + * 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 + } + + @Override + public void updateColours(Object source) + { + AlignmentViewPanel ap = (AlignmentViewPanel) source; + // ignore events from panels not used to colour this view + if (!getViewer().isUsedforcolourby(ap)) + { + return; + } + if (!isLoadingFromArchive()) + { + updateStructureColours(ap); + } + } + + /** + * Sets the list of chains to display (as "pdbid:chain"), where an empty list + * means show all + * + * @param chains + */ + public void setChainsToShow(List chains) + { + chainsToShow = 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 (chainsToShow.isEmpty()) + { + return true; + } + return chainsToShow.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 + *
    + *
  • 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 + * @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++) + { + StructureMapping[] mappings = getSsm().getMapping(files[pdbfnum]); + + /* + * 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 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 residueRanges = mapping + .getPDBResNumRanges(seqStartPos, seqEndPos); + if (!residueRanges.isEmpty()) + { + for (int[] range : residueRanges) + { + model.addRange(pdbfnum, range[0], range[1], chainCd); + } + } + } + } + } + } + } + + return model; + } + + /** + * 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); + } + + /** + * Build a data structure which records contiguous subsequences for each colour. + * From this we can easily generate the Chimera command for colour by sequence. + * + *
 +   * Color
 +   *     Model number
 +   *         Chain
 +   *             list of start/end ranges
 +   * 
+ * + * Ordering is by order of addition (for colours and positions), natural + * ordering (for models and chains) + * + * @param viewPanel + * @return + */ - protected Map buildColoursMap( ++ public Map buildColoursMap( + 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 = getSequenceRenderer(viewPanel); + String[] files = getStructureFiles(); + + Map colourMap = new LinkedHashMap<>(); + Color lastColour = null; + + for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++) + { + StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]); + + if (mapping == null || mapping.length < 1) + { + continue; + } + + int startPos = -1, lastPos = -1; + String lastChain = ""; + for (int s = 0; s < sequence[pdbfnum].length; s++) + { + for (int sp, m = 0; m < mapping.length; m++) + { + final SequenceI seq = sequence[pdbfnum][s]; + if (mapping[m].getSequence() == seq + && (sp = al.findIndex(seq)) > -1) + { + SequenceI asp = al.getSequenceAt(sp); + for (int r = 0; r < asp.getLength(); r++) + { + // no mapping to gaps in sequence + if (Comparison.isGap(asp.getCharAt(r))) + { + continue; + } + int pos = mapping[m].getPDBResNum(asp.findPosition(r)); + + if (pos < 1 || pos == lastPos) + { + continue; + } + + Color colour = sr.getResidueColour(seq, r, finder); + + /* + * hidden regions are shown gray or, optionally, ignored + */ + if (!cs.isVisible(r)) + { + if (hideHiddenRegions) + { + 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) + { - ChimeraCommands.addMapRange(colourMap, lastColour, ++ ChimeraCommands.addAtomSpecRange(colourMap, lastColour, + pdbfnum, startPos, + lastPos, lastChain); + } + startPos = pos; + } + lastColour = colour; + lastPos = pos; + lastChain = chain; + } + // final colour range + if (lastColour != null) + { - ChimeraCommands.addMapRange(colourMap, lastColour, pdbfnum, ++ ChimeraCommands.addAtomSpecRange(colourMap, lastColour, ++ pdbfnum, + startPos, lastPos, lastChain); + } + // break; + } + } + } + } + return colourMap; + } } diff --cc test/jalview/ext/rbvi/chimera/ChimeraCommandsTest.java index 6dd5cc7,06a09df..1d620c4 --- a/test/jalview/ext/rbvi/chimera/ChimeraCommandsTest.java +++ b/test/jalview/ext/rbvi/chimera/ChimeraCommandsTest.java @@@ -50,96 -45,8 +50,97 @@@ import java.util.Map import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import junit.extensions.PA; + public class ChimeraCommandsTest { - + private SequenceRenderer sr; ++ ++ private String[] files; + + private AAStructureBindingModel mockBinding = new AAStructureBindingModel( + null, null) + { + @Override + public void releaseReferences(Object svl) + { + } + + @Override + public void highlightAtoms(List atoms) + { + } + + @Override + public List getChainNames() + { + return null; + } + + @Override + public void setJalviewColourScheme(ColourSchemeI cs) + { + } + + @Override + public String superposeStructures(AlignmentI[] alignments, + int[] structureIndices, HiddenColumns[] hiddenCols) + { + return null; + } + + @Override + public void setBackgroundColour(Color col) + { + } + + @Override + protected String[] getColourBySequenceCommands(String[] files, + AlignmentViewPanel avp) + { + return null; + } + + @Override + public jalview.api.SequenceRenderer getSequenceRenderer( + AlignmentViewPanel alignment) + { + return sr; + } + + @Override + protected void colourBySequence(String[] colourBySequenceCommands) + { + } + + @Override + public void colourByChain() + { + } + + @Override + public void colourByCharge() + { + } + + @Override + public FeatureRenderer getFeatureRenderer(AlignmentViewPanel alignment) + { + return null; + } + + @Override + public String[] getStructureFiles() + { - return null; ++ return files; + } + + @Override + public String getModelSpec(int model) + { + return "#" + String.valueOf(model); + } + }; @BeforeClass(alwaysRun = true) public void setUpJvOptionPane() @@@ -151,17 -58,17 +152,16 @@@ @Test(groups = { "Functional" }) public void testBuildColourCommands() { -- - Map map = new LinkedHashMap(); + Map map = new LinkedHashMap<>(); - ChimeraCommands.addMapRange(map, Color.blue, 0, 2, 5, "A"); - ChimeraCommands.addMapRange(map, Color.blue, 0, 7, 7, "B"); - ChimeraCommands.addMapRange(map, Color.blue, 0, 9, 23, "A"); - ChimeraCommands.addMapRange(map, Color.blue, 1, 1, 1, "A"); - ChimeraCommands.addMapRange(map, Color.blue, 1, 4, 7, "B"); - ChimeraCommands.addMapRange(map, Color.yellow, 1, 8, 8, "A"); - ChimeraCommands.addMapRange(map, Color.yellow, 1, 3, 5, "A"); - ChimeraCommands.addMapRange(map, Color.red, 0, 3, 5, "A"); - ChimeraCommands.addMapRange(map, Color.red, 0, 6, 9, "A"); + ChimeraCommands.addAtomSpecRange(map, Color.blue, 0, 2, 5, "A"); + ChimeraCommands.addAtomSpecRange(map, Color.blue, 0, 7, 7, "B"); + ChimeraCommands.addAtomSpecRange(map, Color.blue, 0, 9, 23, "A"); + ChimeraCommands.addAtomSpecRange(map, Color.blue, 1, 1, 1, "A"); + ChimeraCommands.addAtomSpecRange(map, Color.blue, 1, 4, 7, "B"); + ChimeraCommands.addAtomSpecRange(map, Color.yellow, 1, 8, 8, "A"); + ChimeraCommands.addAtomSpecRange(map, Color.yellow, 1, 3, 5, "A"); + ChimeraCommands.addAtomSpecRange(map, Color.red, 0, 3, 5, "A"); + ChimeraCommands.addAtomSpecRange(map, Color.red, 0, 6, 9, "A"); // 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 @@@ -186,10 -91,10 +186,10 @@@ * start with just one feature/value... */ featuresMap.put("chain", featureValues); - ChimeraCommands.addMapRange(featureValues, "X", 0, 8, 20, "A"); + ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 8, 20, "A"); List commands = ChimeraCommands - .buildSetAttributeCommands(featuresMap); + .buildSetAttributeCommands(featuresMap, mockBinding); assertEquals(1, commands.size()); /* @@@ -199,28 -104,25 +199,28 @@@ assertEquals(commands.get(0), "setattr r jv_chain 'X' #0:8-20.A"); // add same feature value, overlapping range - ChimeraCommands.addMapRange(featureValues, "X", 0, 3, 9, "A"); + ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 3, 9, "A"); // same feature value, contiguous range - ChimeraCommands.addMapRange(featureValues, "X", 0, 21, 25, "A"); + ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 21, 25, "A"); - commands = ChimeraCommands.buildSetAttributeCommands(featuresMap); + commands = ChimeraCommands.buildSetAttributeCommands(featuresMap, + mockBinding); assertEquals(1, commands.size()); assertEquals(commands.get(0), "setattr r jv_chain 'X' #0:3-25.A"); // same feature value and model, different chain - ChimeraCommands.addMapRange(featureValues, "X", 0, 21, 25, "B"); + ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 21, 25, "B"); // same feature value and chain, different model - ChimeraCommands.addMapRange(featureValues, "X", 1, 26, 30, "A"); + ChimeraCommands.addAtomSpecRange(featureValues, "X", 1, 26, 30, "A"); - commands = ChimeraCommands.buildSetAttributeCommands(featuresMap); + commands = ChimeraCommands.buildSetAttributeCommands(featuresMap, + mockBinding); assertEquals(1, commands.size()); assertEquals(commands.get(0), "setattr r jv_chain 'X' #0:3-25.A,21-25.B|#1:26-30.A"); // same feature, different value - ChimeraCommands.addMapRange(featureValues, "Y", 0, 40, 50, "A"); + ChimeraCommands.addAtomSpecRange(featureValues, "Y", 0, 40, 50, "A"); - commands = ChimeraCommands.buildSetAttributeCommands(featuresMap); + commands = ChimeraCommands.buildSetAttributeCommands(featuresMap, + mockBinding); assertEquals(2, commands.size()); // commands are ordered by feature type but not by value // so use contains to test for the expected command: @@@ -280,9 -181,9 +280,9 @@@ cs.addElement(4); af.getViewport().setColumnSelection(cs); af.hideSelColumns_actionPerformed(null); - SequenceRenderer sr = new SequenceRenderer(af.getViewport()); + sr = new SequenceRenderer(af.getViewport()); SequenceI[][] seqs = new SequenceI[][] { { seq1 }, { seq2 } }; -- String[] files = new String[] { "seq1.pdb", "seq2.pdb" }; ++ files = new String[] { "seq1.pdb", "seq2.pdb" }; StructureSelectionManager ssm = new StructureSelectionManager(); /* @@@ -300,16 -201,11 +300,18 @@@ "B", map, null); ssm.addStructureMapping(sm2); - StructureMappingcommandSet[] commands = ChimeraCommands - .getColourBySequenceCommand(ssm, files, seqs, sr, af.alignPanel); + /* + * put data into the mock binding object + */ + PA.setValue(mockBinding, "ssm", ssm); + PA.setValue(mockBinding, "sequence", seqs); + ++ Map colourMap = mockBinding ++ .buildColoursMap(af.alignPanel); + String[] commands = ChimeraCommands - .getColourBySequenceCommand(files, af.alignPanel, mockBinding); ++ .getColourBySequenceCommand(colourMap, mockBinding); assertEquals(1, commands.length); - assertEquals(1, commands[0].commands.length); - String theCommand = commands[0].commands[0]; + String theCommand = commands[0]; // M colour is #82827d (see strand.html help page) assertTrue(theCommand.contains("color #82827d #0:21.A|#1:21.B")); // H colour is #60609f diff --cc utils/testnglibs/testng-sources.jar index 7a80303,7a80303..5e4c948 Binary files differ