X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FSearchResults.java;h=880f9705f8d8624faf19d8fb44fe40fa6a3c6e63;hb=57738a1f3c19b1c3a00bd3ac5108f8cd0af32f99;hp=58f85178e273e8f24a50879312e7f3ebfc27aae5;hpb=435792460e417edc981c308f917f2ff5a7829971;p=jalview.git diff --git a/src/jalview/datamodel/SearchResults.java b/src/jalview/datamodel/SearchResults.java index 58f8517..880f970 100755 --- a/src/jalview/datamodel/SearchResults.java +++ b/src/jalview/datamodel/SearchResults.java @@ -21,7 +21,6 @@ package jalview.datamodel; import java.util.ArrayList; -import java.util.Arrays; import java.util.BitSet; import java.util.List; @@ -34,8 +33,9 @@ import java.util.List; */ public class SearchResults implements SearchResultsI { + private int count; - private List matches = new ArrayList(); + private List matches = new ArrayList<>(); /** * One match consists of a sequence reference, start and end positions. @@ -43,20 +43,23 @@ public class SearchResults implements SearchResultsI */ public class Match implements SearchResultMatchI { - SequenceI sequence; + final SequenceI sequence; /** * Start position of match in sequence (base 1) */ - int start; + final int start; /** * End position (inclusive) (base 1) */ - int end; + final int end; /** - * Constructor + * create a Match on a range of sequence. Match always holds region in + * forwards order, even if given in reverse order (such as from a mapping to + * a reverse strand); this avoids trouble for routines that highlight search + * results etc * * @param seq * a sequence @@ -81,32 +84,26 @@ public class SearchResults implements SearchResultsI } else { + // TODO: JBP could mark match as being specified in reverse direction + // for use + // by caller ? e.g. visualizing reverse strand highlight this.start = end; this.end = start; } } - /* (non-Javadoc) - * @see jalview.datamodel.SearchResultMatchI#getSequence() - */ @Override public SequenceI getSequence() { return sequence; } - /* (non-Javadoc) - * @see jalview.datamodel.SearchResultMatchI#getStart() - */ @Override public int getStart() { return start; } - /* (non-Javadoc) - * @see jalview.datamodel.SearchResultMatchI#getEnd() - */ @Override public int getEnd() { @@ -114,33 +111,18 @@ public class SearchResults implements SearchResultsI } /** - * Returns the string of characters in the matched region, prefixed by the - * start position, e.g. "12CGT" or "208K" + * Returns a representation as "seqid/start-end" */ @Override public String toString() { - final int from = Math.max(start - 1, 0); - String startPosition = String.valueOf(from); - return startPosition + getCharacters(); - } - - /* (non-Javadoc) - * @see jalview.datamodel.SearchResultMatchI#getCharacters() - */ - @Override - public String getCharacters() - { - char[] chars = sequence.getSequence(); - // convert start/end to base 0 (with bounds check) - final int from = Math.max(start - 1, 0); - final int to = Math.min(end, chars.length + 1); - return String.valueOf(Arrays.copyOfRange(chars, from, to)); - } - - public void setSequence(SequenceI seq) - { - this.sequence = seq; + StringBuilder sb = new StringBuilder(); + if (sequence != null) + { + sb.append(sequence.getName()).append("/"); + } + sb.append(start).append("-").append(end); + return sb.toString(); } /** @@ -169,33 +151,59 @@ public class SearchResults implements SearchResultsI return false; } SearchResultMatchI m = (SearchResultMatchI) obj; - return (sequence == m.getSequence() && start == m.getStart() && end == m - .getEnd()); + return (sequence == m.getSequence() && start == m.getStart() + && end == m.getEnd()); + } + + @Override + public boolean contains(SequenceI seq, int from, int to) + { + return (sequence == seq && start <= from && end >= to); } } - /* (non-Javadoc) - * @see jalview.datamodel.SearchResultsI#addResult(jalview.datamodel.SequenceI, int, int) - */ @Override - public void addResult(SequenceI seq, int start, int end) + public SearchResultMatchI addResult(SequenceI seq, int start, int end) + { + Match m = new Match(seq, start, end); + if (!matches.contains(m)) + { + matches.add(m); + count++; + } + return m; + } + + @Override + public void addResult(SequenceI seq, int[] positions) { - matches.add(new Match(seq, start, end)); + /* + * we only increment the match count by 1 - or not at all, + * if the matches are all duplicates of existing + */ + int beforeCount = count; + for (int i = 0; i < positions.length - 1; i += 2) + { + addResult(seq, positions[i], positions[i + 1]); + } + if (count > beforeCount) + { + count = beforeCount + 1; + } } - /* (non-Javadoc) - * @see jalview.datamodel.SearchResultsI#involvesSequence(jalview.datamodel.SequenceI) - */ @Override public boolean involvesSequence(SequenceI sequence) { + final int start = sequence.getStart(); + final int end = sequence.getEnd(); + SequenceI ds = sequence.getDatasetSequence(); - Match m; - for (SearchResultMatchI _m : matches) + for (SearchResultMatchI m : matches) { - m = (Match) _m; - if (m.sequence != null - && (m.sequence == sequence || m.sequence == ds)) + SequenceI matched = m.getSequence(); + if (matched != null && (matched == sequence || matched == ds) + && (m.getEnd() >= start) && (m.getStart() <= end)) { return true; } @@ -203,9 +211,6 @@ public class SearchResults implements SearchResultsI return false; } - /* (non-Javadoc) - * @see jalview.datamodel.SearchResultsI#getResults(jalview.datamodel.SequenceI, int, int) - */ @Override public int[] getResults(SequenceI sequence, int start, int end) { @@ -224,20 +229,15 @@ public class SearchResults implements SearchResultsI m = (Match) _m; mfound = false; - if (m.sequence == sequence) - { - mfound = true; - // locate aligned position - matchStart = sequence.findIndex(m.start) - 1; - matchEnd = sequence.findIndex(m.end) - 1; - } - else if (m.sequence == sequence.getDatasetSequence()) + if (m.sequence == sequence + || m.sequence == sequence.getDatasetSequence()) { mfound = true; - // locate region in local context matchStart = sequence.findIndex(m.start) - 1; - matchEnd = sequence.findIndex(m.end) - 1; + matchEnd = m.start == m.end ? matchStart + : sequence.findIndex(m.end) - 1; } + if (mfound) { if (matchStart <= end && matchEnd >= start) @@ -269,7 +269,7 @@ public class SearchResults implements SearchResultsI else { // debug - // System.err.println("Outwith bounds!" + matchStart+">"+end +" or " + // System.err.println("Outwith bounds!" + matchStart+">"+end +" or " // + matchEnd+"<"+start); } } @@ -282,9 +282,12 @@ public class SearchResults implements SearchResultsI { int count = 0; BitSet mask = new BitSet(); + int startRes = sqcol.getStartRes(); + int endRes = sqcol.getEndRes(); + for (SequenceI s : sqcol.getSequences()) { - int[] cols = getResults(s, sqcol.getStartRes(), sqcol.getEndRes()); + int[] cols = getResults(s, startRes, endRes); if (cols != null) { for (int pair = 0; pair < cols.length; pair += 2) @@ -302,54 +305,18 @@ public class SearchResults implements SearchResultsI return count; } - /* (non-Javadoc) - * @see jalview.datamodel.SearchResultsI#getSize() - */ - @Override - public int getSize() - { - return matches.size(); - } - - /* (non-Javadoc) - * @see jalview.datamodel.SearchResultsI#getResultSequence(int) - */ - @Override - public SequenceI getResultSequence(int index) - { - return matches.get(index).getSequence(); - } - - /* (non-Javadoc) - * @see jalview.datamodel.SearchResultsI#getResultStart(int) - */ - @Override - public int getResultStart(int i) - { - return matches.get(i).getStart(); - } - - /* (non-Javadoc) - * @see jalview.datamodel.SearchResultsI#getResultEnd(int) - */ @Override - public int getResultEnd(int i) + public int getCount() { - return matches.get(i).getEnd(); + return count; } - /* (non-Javadoc) - * @see jalview.datamodel.SearchResultsI#isEmpty() - */ @Override public boolean isEmpty() { return matches.isEmpty(); } - /* (non-Javadoc) - * @see jalview.datamodel.SearchResultsI#getResults() - */ @Override public List getResults() { @@ -357,44 +324,23 @@ public class SearchResults implements SearchResultsI } /** - * Return the results as a string of characters (bases) prefixed by start - * position(s). Meant for use when the context ensures that all matches are to - * regions of the same sequence (otherwise the result is meaningless). + * Return the results as a list of matches [seq1/from-to, seq2/from-to, ...] * * @return */ @Override public String toString() { - StringBuilder result = new StringBuilder(256); - for (SearchResultMatchI m : matches) - { - result.append(m.toString()); - } - return result.toString(); - } - - /** - * Return the results as a string of characters (bases). Meant for use when - * the context ensures that all matches are to regions of the same sequence - * (otherwise the result is meaningless). - * - * @return - */ - public String getCharacters() - { - StringBuilder result = new StringBuilder(256); - for (SearchResultMatchI m : matches) - { - result.append(m.getCharacters()); - } - return result.toString(); + return matches == null ? "" : matches.toString(); } /** - * Hashcode is has derived from the list of matches. This ensures that when - * two SearchResults objects satisfy the test for equals(), then they have the + * Hashcode is derived from the list of matches. This ensures that when two + * SearchResults objects satisfy the test for equals(), then they have the * same hashcode. + * + * @see Match#hashCode() + * @see java.util.AbstractList#hashCode() */ @Override public int hashCode() @@ -403,8 +349,10 @@ public class SearchResults implements SearchResultsI } /** - * Two SearchResults are considered equal if they contain the same matches in - * the same order. + * Two SearchResults are considered equal if they contain the same matches + * (Sequence, start position, end position) in the same order + * + * @see Match#equals(Object) */ @Override public boolean equals(Object obj) @@ -416,4 +364,10 @@ public class SearchResults implements SearchResultsI SearchResultsI sr = (SearchResultsI) obj; return matches.equals(sr.getResults()); } + + @Override + public void addSearchResults(SearchResultsI toAdd) + { + matches.addAll(toAdd.getResults()); + } }