From 0ccaf35f7e6a5cc62d4f433b39d574d0aa4b2d26 Mon Sep 17 00:00:00 2001 From: James Procter Date: Thu, 1 Jun 2023 13:56:53 +0100 Subject: [PATCH] JAL-4134 properly resolve positions in associated aligned sequence for matrix group column-wise selection actions in tree and annotation panel --- src/jalview/gui/AnnotationPanel.java | 41 ++++++++++++++++---- src/jalview/gui/TreeCanvas.java | 14 +++++-- .../ws/datamodel/MappableContactMatrixI.java | 14 ++++++- .../datamodel/alphafold/MappableContactMatrix.java | 1 + 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/jalview/gui/AnnotationPanel.java b/src/jalview/gui/AnnotationPanel.java index 9970702..8e04048 100755 --- a/src/jalview/gui/AnnotationPanel.java +++ b/src/jalview/gui/AnnotationPanel.java @@ -72,6 +72,7 @@ import jalview.util.MessageManager; import jalview.util.Platform; import jalview.viewmodel.ViewportListenerI; import jalview.viewmodel.ViewportRanges; +import jalview.ws.datamodel.MappableContactMatrixI; import jalview.ws.datamodel.alphafold.PAEContactMatrix; /** @@ -667,24 +668,48 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, if (matrix.hasGroups()) { SequenceI rseq = clicked.sequenceRef; - BitSet grp = matrix.getGroupsFor(currentX); + BitSet grp = new BitSet(); + grp.or(matrix.getGroupsFor(currentX)); // TODO: cXci needs to be mapped to real groups for (int c = fr; c <= to; c++) { BitSet additionalGrp = matrix.getGroupsFor(c); grp.or(additionalGrp); } + HiddenColumns hc = av.getAlignment().getHiddenColumns(); - for (int p = grp.nextSetBit(0); p >= 0; p = grp + ColumnSelection cs = av.getColumnSelection(); + + for (int p=grp.nextSetBit(0); p >= 0; p = grp .nextSetBit(p + 1)) { - int offp = (rseq != null) - ? rseq.findIndex(rseq.getStart() - 1 + p) - : p; - - if (!av.hasHiddenColumns() || hc.isVisible(offp)) + if (matrix instanceof MappableContactMatrixI) { - av.getColumnSelection().addElement(offp); + // find the end of this run of set bits + int nextp = grp.nextClearBit(p)-1; + int[] pos = ((MappableContactMatrixI)matrix).getMappedPositionsFor(rseq, p,nextp); + p=nextp; + + if (pos!=null) + { + for (int pos_p = pos[0];pos_p<=pos[1];pos_p++) + { + int col = rseq.findIndex(pos_p)-1; + if (col>=0 && (!av.hasHiddenColumns() || hc.isVisible(col))) + { + cs.addElement(col); + } + } + } + } else { + int offp = (rseq != null) + ? rseq.findIndex(rseq.getStart() - 1 + p) + : p; + + if (!av.hasHiddenColumns() || hc.isVisible(offp)) + { + cs.addElement(offp); + } } } } diff --git a/src/jalview/gui/TreeCanvas.java b/src/jalview/gui/TreeCanvas.java index 2bdfc27..55ce44a 100755 --- a/src/jalview/gui/TreeCanvas.java +++ b/src/jalview/gui/TreeCanvas.java @@ -1148,14 +1148,22 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, if (aa != null) { ContactMatrixI cm = av.getContactMatrix(aa); + // generally, we assume cm has 1:1 mapping to annotation row - probably wrong + // but.. if if (cm instanceof MappableContactMatrixI) { + int[] pos; + // use the mappable's mapping - always the case for PAE Matrices so good + // for 2.11.3 MappableContactMatrixI mcm = (MappableContactMatrixI) cm; - int pos[]=mcm.getMappedPositionsFor(rseq, colm+1); - if (pos!=null) + pos = mcm.getMappedPositionsFor(rseq, colm + 1); + // finally, look up the position of the column + if (pos != null) { - offp=rseq.findIndex(pos[0]); + offp = rseq.findIndex(pos[0]); } + } else { + offp = colm; } } if (offp<=0) diff --git a/src/jalview/ws/datamodel/MappableContactMatrixI.java b/src/jalview/ws/datamodel/MappableContactMatrixI.java index b8a9779..9762428 100644 --- a/src/jalview/ws/datamodel/MappableContactMatrixI.java +++ b/src/jalview/ws/datamodel/MappableContactMatrixI.java @@ -51,7 +51,7 @@ public interface MappableContactMatrixI extends ContactMatrixI MapList getMapFor(SequenceI sequenceRef); /** - * Locate a position in the mapped sequence for a column in the matrix - use + * Locate a position in the mapped sequence for a single column in the matrix. * this to resolve positions corresponding to column clusters * * @param localFrame @@ -61,4 +61,16 @@ public interface MappableContactMatrixI extends ContactMatrixI * @return sequence position(s) corresponding to column in contact matrix */ int[] getMappedPositionsFor(SequenceI localFrame, int column); + + /** + * Locate a position in the mapped sequence for a contiguous range of columns in the matrix + * use this to resolve positions corresponding to column clusters + * + * @param localFrame + * - sequence derivced from reference sequence + * @param column + * - matrix row/column + * @return sequence position(s) corresponding to column in contact matrix + */ + int[] getMappedPositionsFor(SequenceI localFrame, int from, int to); } diff --git a/src/jalview/ws/datamodel/alphafold/MappableContactMatrix.java b/src/jalview/ws/datamodel/alphafold/MappableContactMatrix.java index 0e617d7..d545741 100644 --- a/src/jalview/ws/datamodel/alphafold/MappableContactMatrix.java +++ b/src/jalview/ws/datamodel/alphafold/MappableContactMatrix.java @@ -186,6 +186,7 @@ public abstract class MappableContactMatrix> return getMappedPositionsFor(localFrame, column, column); } + @Override public int[] getMappedPositionsFor(final SequenceI localFrame, int from, int to) { -- 1.7.10.2