X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FColumnSelection.java;h=3c2d1664bba6c5adbcfd622cfe09d74d9d91d46f;hb=4b7d3640209c4434d569c746672cf9eed4250ace;hp=4d69fa4ef3ea1355c83ca89ffe2454d9c4ed20d2;hpb=1b911af46e474fd504a4d505327e02b684d9a397;p=jalview.git diff --git a/src/jalview/datamodel/ColumnSelection.java b/src/jalview/datamodel/ColumnSelection.java index 4d69fa4..3c2d166 100644 --- a/src/jalview/datamodel/ColumnSelection.java +++ b/src/jalview/datamodel/ColumnSelection.java @@ -20,14 +20,14 @@ */ package jalview.datamodel; -import jalview.util.ShiftList; -import jalview.viewmodel.annotationfilter.AnnotationFilterParameter; -import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.SearchableAnnotationField; - import java.util.ArrayList; import java.util.BitSet; import java.util.Collections; import java.util.List; +import java.util.regex.PatternSyntaxException; + +import jalview.viewmodel.annotationfilter.AnnotationFilterParameter; +import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.SearchableAnnotationField; /** * Data class holding the selected columns and hidden column ranges for a view. @@ -60,7 +60,7 @@ public class ColumnSelection */ IntList() { - order = new ArrayList(); + order = new ArrayList<>(); _uorder = Collections.unmodifiableList(order); selected = new BitSet(); } @@ -106,7 +106,7 @@ public class ColumnSelection void remove(int col) { - Integer colInt = new Integer(col); + Integer colInt = Integer.valueOf(col); if (selected.get(col)) { @@ -204,7 +204,7 @@ public class ColumnSelection // clear shifted bits and update List of selected columns selected.clear(temp); mask.set(temp - change); - order.set(i, new Integer(temp - change)); + order.set(i, Integer.valueOf(temp - change)); } } // lastly update the bitfield all at once @@ -231,7 +231,7 @@ public class ColumnSelection */ List getRanges() { - List rlist = new ArrayList(); + List rlist = new ArrayList<>(); if (selected.isEmpty()) { return rlist; @@ -264,9 +264,7 @@ public class ColumnSelection } } - IntList selection = new IntList(); - - HiddenColumns hiddenColumns = new HiddenColumns(); + private IntList selection = new IntList(); /** * Add a column to the selection @@ -311,7 +309,7 @@ public class ColumnSelection Integer colInt; for (int i = start; i < end; i++) { - colInt = new Integer(i); + colInt = Integer.valueOf(i); if (selection.contains(colInt)) { selection.remove(colInt); @@ -356,6 +354,22 @@ public class ColumnSelection } /** + * + */ + public boolean intersects(int from, int to) + { + // TODO: do this in a more efficient bitwise way + for (int f = from; f <= to; f++) + { + if (selection.isSelected(f)) + { + return true; + } + } + return false; + } + + /** * Answers true if no columns are selected, else false */ public boolean isEmpty() @@ -391,93 +405,6 @@ public class ColumnSelection return selection.getMinColumn(); } - /** - * propagate shift in alignment columns to column selection - * - * @param start - * beginning of edit - * @param left - * shift in edit (+ve for removal, or -ve for inserts) - */ - /* public List compensateForEdit(int start, int change) - { - selection.compensateForEdits(start, change); - return hiddenColumns.compensateForEdit(start, change, this); - } - */ - /** - * propagate shift in alignment columns to column selection special version of - * compensateForEdit - allowing for edits within hidden regions - * - * @param start - * beginning of edit - * @param left - * shift in edit (+ve for removal, or -ve for inserts) - */ - private void compensateForDelEdits(int start, int change) - { - selection.compensateForEdits(start, change); - hiddenColumns.compensateForDelEdits(start, change); - } - - /** - * Adjust hidden column boundaries based on a series of column additions or - * deletions in visible regions. - * - * @param shiftrecord - * @return - */ - private ShiftList compensateForEdits(ShiftList shiftrecord) - { - if (shiftrecord != null) - { - final List shifts = shiftrecord.getShifts(); - if (shifts != null && shifts.size() > 0) - { - int shifted = 0; - for (int i = 0, j = shifts.size(); i < j; i++) - { - int[] sh = shifts.get(i); - compensateForDelEdits(shifted + sh[0], sh[1]); - shifted -= sh[1]; - } - } - return shiftrecord.getInverse(); - } - return null; - } - - - /** - * remove any hiddenColumns or selected columns and shift remaining based on a - * series of position, range deletions. - * - * @param deletions - */ - private void pruneDeletions(ShiftList deletions) - { - if (deletions != null) - { - final List shifts = deletions.getShifts(); - if (shifts != null && shifts.size() > 0) - { - hiddenColumns.pruneDeletions(shifts); - - if (selection != null && selection.size() > 0) - { - selection.pruneColumnList(shifts); - if (selection != null && selection.size() == 0) - { - selection = null; - } - } - // and shift the rest. - this.compensateForEdits(deletions); - } - } - } - - public void hideSelectedColumns(AlignmentI al) { synchronized (selection) @@ -491,7 +418,6 @@ public class ColumnSelection } - /** * Hides the specified column and any adjacent selected columns * @@ -534,10 +460,6 @@ public class ColumnSelection hidden.hideColumns(min, max); } - - - - /** * Copy constructor * @@ -558,11 +480,6 @@ public class ColumnSelection { } - - - - - /** * Invert the column selection from first to end-1. leaves hiddenColumns * untouched (and unselected) @@ -572,7 +489,7 @@ public class ColumnSelection */ public void invertColumnSelection(int first, int width, AlignmentI al) { - boolean hasHidden = al.getHiddenColumns().hasHidden(); + boolean hasHidden = al.getHiddenColumns().hasHiddenColumns(); for (int i = first; i < width; i++) { if (contains(i)) @@ -590,41 +507,28 @@ public class ColumnSelection } /** - * add in any unselected columns from the given column selection, excluding - * any that are hidden. - * - * @param colsel - */ - public void addElementsFrom(ColumnSelection colsel) - { - if (colsel != null && !colsel.isEmpty()) - { - for (Integer col : colsel.getSelected()) - { - if (hiddenColumns != null - && hiddenColumns.isVisible(col.intValue())) - { - selection.add(col); - } - } - } - } - - /** - * set the selected columns the given column selection, excluding any columns - * that are hidden. + * set the selected columns to the given column selection, excluding any + * columns that are hidden. * * @param colsel */ - public void setElementsFrom(ColumnSelection colsel) + public void setElementsFrom(ColumnSelection colsel, + HiddenColumns hiddenColumns) { selection = new IntList(); if (colsel.selection != null && colsel.selection.size() > 0) { - if (hiddenColumns.hasHidden()) + if (hiddenColumns.hasHiddenColumns()) { // only select visible columns in this columns selection - addElementsFrom(colsel); + for (Integer col : colsel.getSelected()) + { + if (hiddenColumns != null + && hiddenColumns.isVisible(col.intValue())) + { + selection.add(col); + } + } } else { @@ -638,254 +542,167 @@ public class ColumnSelection } /** - * Add gaps into the sequences aligned to profileseq under the given - * AlignmentView * - * @param profileseq - * @param al - * - alignment to have gaps inserted into it - * @param input - * - alignment view where sequence corresponding to profileseq is - * first entry - * @return new Column selection for new alignment view, with insertions into - * profileseq marked as hidden. + * @return true if there are columns marked */ - public static ColumnSelection propagateInsertions(SequenceI profileseq, - AlignmentI al, AlignmentView input) + public boolean hasSelectedColumns() { - int profsqpos = 0; - - // return propagateInsertions(profileseq, al, ) - char gc = al.getGapCharacter(); - Object[] alandcolsel = input.getAlignmentAndHiddenColumns(gc); - ColumnSelection nview = (ColumnSelection) alandcolsel[1]; - SequenceI origseq = ((SequenceI[]) alandcolsel[0])[profsqpos]; - nview.propagateInsertions(profileseq, al, origseq); - return nview; + return (selection != null && selection.size() > 0); } /** + * Selects columns where the given annotation matches the provided filter + * condition(s). Any existing column selections are first cleared. Answers the + * number of columns added. * - * @param profileseq - * - sequence in al which corresponds to origseq - * @param al - * - alignment which is to have gaps inserted into it - * @param origseq - * - sequence corresponding to profileseq which defines gap map for - * modifying al + * @param annotations + * @param filterParams + * @return */ - private void propagateInsertions(SequenceI profileseq, AlignmentI al, - SequenceI origseq) + public int filterAnnotations(AlignmentAnnotation ann_row, + AnnotationFilterParameter filterParams) { - char gc = al.getGapCharacter(); - // recover mapping between sequence's non-gap positions and positions - // mapping to view. - pruneDeletions(ShiftList.parseMap(origseq.gapMap())); - int[] viscontigs = hiddenColumns.getVisibleContigs(0, - profileseq.getLength()); - int spos = 0; - int offset = 0; - - // add profile to visible contigs - for (int v = 0; v < viscontigs.length; v += 2) - { - if (viscontigs[v] > spos) - { - StringBuffer sb = new StringBuffer(); - for (int s = 0, ns = viscontigs[v] - spos; s < ns; s++) - { - sb.append(gc); - } - for (int s = 0, ns = al.getHeight(); s < ns; s++) - { - SequenceI sqobj = al.getSequenceAt(s); - if (sqobj != profileseq) - { - String sq = al.getSequenceAt(s).getSequenceAsString(); - if (sq.length() <= spos + offset) - { - // pad sequence - int diff = spos + offset - sq.length() - 1; - if (diff > 0) - { - // pad gaps - sq = sq + sb; - while ((diff = spos + offset - sq.length() - 1) > 0) - { - // sq = sq - // + ((diff >= sb.length()) ? sb.toString() : sb - // .substring(0, diff)); - if (diff >= sb.length()) - { - sq += sb.toString(); - } - else - { - char[] buf = new char[diff]; - sb.getChars(0, diff, buf, 0); - sq += buf.toString(); - } - } - } - sq += sb.toString(); - } - else - { - al.getSequenceAt(s).setSequence( - sq.substring(0, spos + offset) + sb.toString() - + sq.substring(spos + offset)); - } - } - } - // offset+=sb.length(); - } - spos = viscontigs[v + 1] + 1; - } - if ((offset + spos) < profileseq.getLength()) + Annotation[] annotations = ann_row.annotations; + // JBPNote - this method needs to be refactored to become independent of + // viewmodel package + this.clear(); + + if (ann_row.graph == AlignmentAnnotation.CONTACT_MAP && (filterParams + .getThresholdType() == AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD + || filterParams + .getThresholdType() == AnnotationFilterParameter.ThresholdType.BELOW_THRESHOLD)) { - // pad the final region with gaps. - StringBuffer sb = new StringBuffer(); - for (int s = 0, ns = profileseq.getLength() - spos - offset; s < ns; s++) - { - sb.append(gc); - } - for (int s = 0, ns = al.getHeight(); s < ns; s++) + float tVal = filterParams.getThresholdValue(); + if (ann_row.sequenceRef != null) { - SequenceI sqobj = al.getSequenceAt(s); - if (sqobj == profileseq) - { - continue; - } - String sq = sqobj.getSequenceAsString(); - // pad sequence - int diff = origseq.getLength() - sq.length(); - while (diff > 0) + // TODO - get ContactList from AlignmentView for non-seq-ref associatd + for (int column = 0; column < annotations.length; column++) { - // sq = sq - // + ((diff >= sb.length()) ? sb.toString() : sb - // .substring(0, diff)); - if (diff >= sb.length()) + if (ann_row.annotations[column] == null) { - sq += sb.toString(); + continue; } - else + + int cpos = ann_row.sequenceRef.findPosition(column) - 1; + ContactListI clist = ann_row.sequenceRef + .getContactListFor(ann_row, cpos); + for (int row = column + 8, rowEnd = clist + .getContactHeight(); row < rowEnd; row++) { - char[] buf = new char[diff]; - sb.getChars(0, diff, buf, 0); - sq += buf.toString(); + if (filterParams + .getThresholdType() == AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD + ? (clist.getContactAt(row) > tVal) + : (clist.getContactAt(row) < tVal)) + { + addElement(column); + break; + // int column_forrowpos = ann_row.sequenceRef.findIndex(row + 1); + // addElement(column_forrowpos); + } } - diff = origseq.getLength() - sq.length(); } } + return selection.size(); } - } - - /** - * - * @return true if there are columns marked - */ - public boolean hasSelectedColumns() - { - return (selection != null && selection.size() > 0); - } - - - public boolean filterAnnotations(Annotation[] annotations, - AnnotationFilterParameter filterParams) - { - // JBPNote - this method needs to be refactored to become independent of - // viewmodel package - hiddenColumns.revealAllHiddenColumns(this); - this.clear(); - int count = 0; + int addedCount = 0; + int column = 0; do { - if (annotations[count] != null) + Annotation ann = annotations[column]; + if (ann != null) { - - boolean itemMatched = false; - - if (filterParams.getThresholdType() == AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD - && annotations[count].value >= filterParams - .getThresholdValue()) + float value = ann.value; + boolean matched = false; + + /* + * filter may have multiple conditions - + * these are or'd until a match is found + */ + if (filterParams + .getThresholdType() == AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD + && value > filterParams.getThresholdValue()) { - itemMatched = true; + matched = true; } - if (filterParams.getThresholdType() == AnnotationFilterParameter.ThresholdType.BELOW_THRESHOLD - && annotations[count].value <= filterParams - .getThresholdValue()) + + if (!matched && filterParams + .getThresholdType() == AnnotationFilterParameter.ThresholdType.BELOW_THRESHOLD + && value < filterParams.getThresholdValue()) { - itemMatched = true; + matched = true; } - if (filterParams.isFilterAlphaHelix() - && annotations[count].secondaryStructure == 'H') + if (!matched && filterParams.isFilterAlphaHelix() + && ann.secondaryStructure == 'H') { - itemMatched = true; + matched = true; } - if (filterParams.isFilterBetaSheet() - && annotations[count].secondaryStructure == 'E') + if (!matched && filterParams.isFilterBetaSheet() + && ann.secondaryStructure == 'E') { - itemMatched = true; + matched = true; } - if (filterParams.isFilterTurn() - && annotations[count].secondaryStructure == 'S') + if (!matched && filterParams.isFilterTurn() + && ann.secondaryStructure == 'S') { - itemMatched = true; + matched = true; } String regexSearchString = filterParams.getRegexString(); - if (regexSearchString != null - && !filterParams.getRegexSearchFields().isEmpty()) + if (!matched && regexSearchString != null) { List fields = filterParams .getRegexSearchFields(); - try - { - if (fields.contains(SearchableAnnotationField.DISPLAY_STRING) - && annotations[count].displayCharacter - .matches(regexSearchString)) - { - itemMatched = true; - } - } catch (java.util.regex.PatternSyntaxException pse) + for (SearchableAnnotationField field : fields) { - if (annotations[count].displayCharacter - .equals(regexSearchString)) + String compareTo = field == SearchableAnnotationField.DISPLAY_STRING + ? ann.displayCharacter // match 'Label' + : ann.description; // and/or 'Description' + if (compareTo != null) { - itemMatched = true; + try + { + if (compareTo.matches(regexSearchString)) + { + matched = true; + } + } catch (PatternSyntaxException pse) + { + if (compareTo.equals(regexSearchString)) + { + matched = true; + } + } + if (matched) + { + break; + } } } - if (fields.contains(SearchableAnnotationField.DESCRIPTION) - && annotations[count].description != null - && annotations[count].description - .matches(regexSearchString)) - { - itemMatched = true; - } } - if (itemMatched) + if (matched) { - this.addElement(count); + this.addElement(column); + addedCount++; } } - count++; - } while (count < annotations.length); - return false; + column++; + } while (column < annotations.length); + + return addedCount; } /** - * Returns a hashCode built from selected columns and hidden column ranges + * Returns a hashCode built from selected columns ranges */ @Override public int hashCode() { - int hashCode = selection.hashCode(); - return hiddenColumns.hashCode(hashCode); + return selection.hashCode(); } /** @@ -916,7 +733,7 @@ public class ColumnSelection return false; } - return this.hiddenColumns.equals(that.hiddenColumns); + return true; } /** @@ -938,8 +755,8 @@ public class ColumnSelection * * @return */ - public boolean markColumns(BitSet markedColumns, int startCol, - int endCol, boolean invert, boolean extendCurrent, boolean toggle) + public boolean markColumns(BitSet markedColumns, int startCol, int endCol, + boolean invert, boolean extendCurrent, boolean toggle) { boolean changed = false; if (!extendCurrent && !toggle)