X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fws%2Fdatamodel%2Falphafold%2FMappableContactMatrix.java;h=0e617d7ca801bda44947705eae21559ea21108f4;hb=e8b8c8601ccdc2fdb2093c5228c071d14182004f;hp=27665d445836a77fd2a2528e7d1bc5f0e58b10a8;hpb=cc3341f9d1465b0226d184be4216d022a62e5cee;p=jalview.git diff --git a/src/jalview/ws/datamodel/alphafold/MappableContactMatrix.java b/src/jalview/ws/datamodel/alphafold/MappableContactMatrix.java index 27665d4..0e617d7 100644 --- a/src/jalview/ws/datamodel/alphafold/MappableContactMatrix.java +++ b/src/jalview/ws/datamodel/alphafold/MappableContactMatrix.java @@ -1,6 +1,8 @@ package jalview.ws.datamodel.alphafold; +import java.awt.Color; import java.util.ArrayList; +import java.util.BitSet; import jalview.datamodel.ContactListI; import jalview.datamodel.ContactListImpl; @@ -12,9 +14,11 @@ import jalview.datamodel.SequenceI; import jalview.util.MapList; import jalview.ws.datamodel.MappableContactMatrixI; -public abstract class MappableContactMatrix> implements MappableContactMatrixI +public abstract class MappableContactMatrix> + implements MappableContactMatrixI { SequenceI refSeq = null; + MapList toSeq = null; /** @@ -22,7 +26,6 @@ public abstract class MappableContactMatrix> */ int length; - @Override public boolean hasReferenceSeq() { @@ -34,15 +37,18 @@ public abstract class MappableContactMatrix> { return refSeq; } + /** * container for groups - defined on matrix columns */ - GroupSet grps=new GroupSet(); + GroupSet grps = new GroupSet(); + @Override public GroupSetI getGroupSet() { return grps; }; + @Override public void setGroupSet(GroupSet makeGroups) { @@ -52,28 +58,33 @@ public abstract class MappableContactMatrix> @Override public MapList getMapFor(SequenceI mapSeq) { - if (refSeq!=null) + if (refSeq != null) { - while (mapSeq!=refSeq && mapSeq.getDatasetSequence()!=null) + while (mapSeq != refSeq && mapSeq.getDatasetSequence() != null) { mapSeq = mapSeq.getDatasetSequence(); } - if (mapSeq!=refSeq) + if (mapSeq != refSeq) { return null; } - } else { - if (mapSeq!=null) { + } + else + { + if (mapSeq != null) + { // our MapList does not concern this seq return null; } } - + return toSeq; } /** - * set the reference sequence and construct the mapping between the start-end positions of given sequence and row/columns of contact matrix + * set the reference sequence and construct the mapping between the start-end + * positions of given sequence and row/columns of contact matrix + * * @param _refSeq */ public void setRefSeq(SequenceI _refSeq) @@ -84,9 +95,13 @@ public abstract class MappableContactMatrix> refSeq = refSeq.getDatasetSequence(); } length = _refSeq.getEnd() - _refSeq.getStart() + 1; -// if (length!=refSeq.getLength() || _refSeq.getStart()!=1) + // if (length!=refSeq.getLength() || _refSeq.getStart()!=1) { - toSeq = new MapList(new int[] { _refSeq.getStart(), _refSeq.getEnd()}, new int[] { 0,length-1}, 1,1); + toSeq = new MapList( + new int[] + { _refSeq.getStart(), _refSeq.getEnd() }, + new int[] + { 0, length - 1 }, 1, 1); } } @@ -161,24 +176,105 @@ public abstract class MappableContactMatrix> return newCM; } - protected abstract T newMappableContactMatrix(SequenceI newRefSeq, + protected abstract T newMappableContactMatrix(SequenceI newRefSeq, MapList newFromMapList); + + @Override + public int[] getMappedPositionsFor(final SequenceI localFrame, + final int column) + { + return getMappedPositionsFor(localFrame, column, column); + } + + public int[] getMappedPositionsFor(final SequenceI localFrame, int from, + int to) + { + if (localFrame == null) + { + throw new Error("Unimplemented when no local sequence given."); + } + SequenceI lf = localFrame, uf = refSeq; + + // check that localFrame is derived from refSeq + // just look for dataset sequences and check they are the same. + // in future we could use DBRefMappings/whatever. + while (lf.getDatasetSequence() != null + || uf.getDatasetSequence() != null) + { + if (lf.getDatasetSequence() != null) + { + lf = lf.getDatasetSequence(); + } + if (uf.getDatasetSequence() != null) + { + uf = uf.getDatasetSequence(); + } + } + if (lf != uf) + { + // could try harder to find a mapping + throw new Error("This Matrix associated with '" + refSeq.getName() + + "' is not mappable for the given localFrame sequence. (" + + localFrame.getName() + ")"); + } + + // now look up from-to matrix columns in toSeq frame + + if (toSeq == null) + { + // no mapping - so we assume 1:1 + return new int[] { from, to }; + } + // from-to are matrix columns + // first locate on reference sequence + + int[] mappedPositions = toSeq.locateInFrom(from, to); + if (mappedPositions==null) + { + return null; + } + + // and now map to localFrame + // from-to columns on the associated sequence should be + // i. restricted to positions in localFrame + // ii. + +// int s = -1, e = -1; +// for (int p = 0; p < mappedPositions.length; p++) +// { +// if (s == -1 && mappedPositions[p] >= localFrame.getStart()) +// { +// s = p; // remember first position within local frame +// } +// if (e == -1 || mappedPositions[p] <= localFrame.getEnd()) +// { +// // update end pointer +// e = p; +// // compute local map +// mappedPositions[p] = localFrame.findIndex(mappedPositions[p]); +// } +// } +// int[] _trimmed = new int[e - s + 1]; +// return _trimmed; + return mappedPositions; + } + @Override public ContactListI getMappableContactList(final SequenceI localFrame, final int column) { final int _column; final int _lcolumn; - if (localFrame==null) + if (localFrame == null) { throw new Error("Unimplemented when no local sequence given."); } // return a ContactListI for column // column is index into localFrame // 1. map column to corresponding column in matrix + final MappableContactMatrix us = this; + _lcolumn = localFrame.findPosition(column); - _lcolumn=localFrame.findPosition(column); - if (toSeq != null) { SequenceI lf = localFrame, uf = refSeq; @@ -214,11 +310,11 @@ public abstract class MappableContactMatrix> } else { - // no mapping + // no mapping _column = _lcolumn; } - // TODO - remove ? this may be a redundant check + // TODO - remove ? this may be a redundant check if (_column < 0 || ((toSeq != null && _column > toSeq.getToHighest()) || (toSeq == null && getHeight() <= _column))) { @@ -234,89 +330,80 @@ public abstract class MappableContactMatrix> int h = 0; for (int p = 0; p < matrixRange.length; p += 2) { - h += 1+Math.abs(matrixRange[p + 1] - matrixRange[p]); + h += 1 + Math.abs(matrixRange[p + 1] - matrixRange[p]); } final int rangeHeight = h; // 3. Construct ContactListImpl instance for just those segments. - + return new ContactListImpl(new ContactListProviderI() { - + public int getColumn() { return column; } + @Override public int getPosition() { return _column; } - + @Override public int getContactHeight() { return rangeHeight; } - + @Override public double getContactAt(int mcolumn) { - if (mcolumn<0 || mcolumn>=rangeHeight) + if (mcolumn < 0 || mcolumn >= rangeHeight) { return -1; } return getElementAt(_column, locateInRange(mcolumn)); - - // this code maps from mcolumn to localFrame - but that isn't what's needed -// int loccolumn = localFrame.findPosition(mcolumn); -// int[] lcolumn=(toSeq==null) ? new int[] {mcolumn} : toSeq.locateInTo(loccolumn,loccolumn); -// if (lcolumn==null || lcolumn[0] < 0 || lcolumn[0] >= rangeHeight) -// { -// return -1; -// } -// return getElementAt(_column,lcolumn[0]); - } - /** - * @return the mcolumn'th position in the matrixRange window on the matrix - */ - private int locateInRange(int mcolumn) - { - int h=0,p=0; - while (h < mcolumn && p+2 < matrixRange.length) - { - h += 1+Math.abs(matrixRange[p + 1] - matrixRange[p]); - p+=2; - } - return matrixRange[p]+mcolumn-h; + // this code maps from mcolumn to localFrame - but that isn't what's + // needed + // int loccolumn = localFrame.findPosition(mcolumn); + // int[] lcolumn=(toSeq==null) ? new int[] {mcolumn} : + // toSeq.locateInTo(loccolumn,loccolumn); + // if (lcolumn==null || lcolumn[0] < 0 || lcolumn[0] >= rangeHeight) + // { + // return -1; + // } + // return getElementAt(_column,lcolumn[0]); } - + @Override public int[] getMappedPositionsFor(int cStart, int cEnd) { if (!hasReferenceSeq()) { - return ContactListProviderI.super.getMappedPositionsFor(cStart, cEnd); + return ContactListProviderI.super.getMappedPositionsFor(cStart, + cEnd); } // map into segment of matrix being shown int realCstart = locateInRange(cStart); int realCend = locateInRange(cEnd); - + // TODO account for discontinuities in the mapping - int[] mappedPositions = toSeq.locateInFrom(realCstart,realCend); - if (mappedPositions!=null) { - int s=-1,e=-1; - for (int p=0;p=localFrame.getStart()) + if (s == -1 && mappedPositions[p] >= localFrame.getStart()) { - s=p; // remember first position within local frame + s = p; // remember first position within local frame } - if (e==-1 || mappedPositions[p]<=localFrame.getEnd()) + if (e == -1 || mappedPositions[p] <= localFrame.getEnd()) { // update end pointer - e=p; + e = p; // compute local map mappedPositions[p] = localFrame.findIndex(mappedPositions[p]); } @@ -324,17 +411,41 @@ public abstract class MappableContactMatrix> } return mappedPositions; } + + /** + * @return the mcolumn'th position in the matrixRange window on the matrix + */ + private int locateInRange(int mcolumn) + { + + int h = 0, p = 0; + while (h < mcolumn && p + 2 < matrixRange.length) + { + h += 1 + Math.abs(matrixRange[p + 1] - matrixRange[p]); + p += 2; + } + return matrixRange[p] + mcolumn - h; + } + + @Override + public Color getColourForGroup() + { + BitSet gp = us.getGroupsFor(_column); + Color col = us.getColourForGroup(gp); + return col; + } }); } /** * get a specific element of the contact matrix in its data-local coordinates - * rather than the mapped frame. Implementations are allowed to throw RunTimeExceptions if _column/i are out of bounds + * rather than the mapped frame. Implementations are allowed to throw + * RunTimeExceptions if _column/i are out of bounds * * @param _column * @param i * @return */ protected abstract double getElementAt(int _column, int i); - + }