X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fworkers%2FColumnCounterSetWorker.java;fp=src%2Fjalview%2Fworkers%2FColumnCounterWorker.java;h=24cb717cf79fe1e8e9f4a807d4a466a256e36866;hb=f063821ed0be9c1581af74643a1aa5798731af65;hp=dd56aaf78c070fd68801536b57aa9d4453bad4dc;hpb=fd18e2c73cd015d4e38ad91da0e5d7532ff0ef42;p=jalview.git diff --git a/src/jalview/workers/ColumnCounterWorker.java b/src/jalview/workers/ColumnCounterSetWorker.java similarity index 60% rename from src/jalview/workers/ColumnCounterWorker.java rename to src/jalview/workers/ColumnCounterSetWorker.java index dd56aaf..24cb717 100644 --- a/src/jalview/workers/ColumnCounterWorker.java +++ b/src/jalview/workers/ColumnCounterSetWorker.java @@ -36,16 +36,16 @@ import java.util.ArrayList; import java.util.List; /** - * A class to compute an alignment annotation with column counts of any - * properties of interest of positions in an alignment.
+ * A class to compute alignment annotations with column counts for a set of + * properties of interest on positions in an alignment.
* This is designed to be extensible, by supplying to the constructor an object - * that computes a count for each residue position, based on the residue value - * and any sequence features at that position. + * that computes a vector of counts for each residue position, based on the + * residue and and sequence features at that position. * */ -class ColumnCounterWorker extends AlignCalcWorker +class ColumnCounterSetWorker extends AlignCalcWorker { - FeatureCounterI counter; + FeatureSetCounterI counter; /** * Constructor registers the annotation for the given alignment frame @@ -53,8 +53,8 @@ class ColumnCounterWorker extends AlignCalcWorker * @param af * @param counter */ - public ColumnCounterWorker(AlignViewportI viewport, - AlignmentViewPanel panel, FeatureCounterI counter) + public ColumnCounterSetWorker(AlignViewportI viewport, + AlignmentViewPanel panel, FeatureSetCounterI counter) { super(viewport, panel); ourAnnots = new ArrayList(); @@ -69,6 +69,7 @@ class ColumnCounterWorker extends AlignCalcWorker @Override public void run() { + boolean annotationAdded = false; try { calcMan.notifyStart(this); @@ -93,7 +94,7 @@ class ColumnCounterWorker extends AlignCalcWorker { try { - computeAnnotations(); + annotationAdded = computeAnnotations(); } catch (IndexOutOfBoundsException x) { // probable race condition. just finish and return without any fuss. @@ -111,7 +112,10 @@ class ColumnCounterWorker extends AlignCalcWorker if (ap != null) { - ap.adjustAnnotationHeight(); + if (annotationAdded) + { + ap.adjustAnnotationHeight(); + } ap.paintAlignment(true); } @@ -120,8 +124,10 @@ class ColumnCounterWorker extends AlignCalcWorker /** * Scan each column of the alignment to calculate a count by feature type. Set * the count as the value of the alignment annotation for that feature type. + * + * @return */ - void computeAnnotations() + boolean computeAnnotations() { FeatureRenderer fr = new FeatureRenderer(alignViewport); // TODO use the commented out code once JAL-2075 is fixed @@ -130,56 +136,91 @@ class ColumnCounterWorker extends AlignCalcWorker // AlignmentView alignmentView = alignViewport.getAlignmentView(false); // AlignmentI alignment = alignmentView.getVisibleAlignment(' '); - // int width = alignmentView.getWidth(); + int rows = counter.getNames().length; + int width = alignment.getWidth(); int height = alignment.getHeight(); - int[] counts = new int[width]; - int max = 0; + int[][] counts = new int[width][rows]; + int max[] = new int[rows]; + for (int crow = 0; crow < rows; crow++) + { + max[crow] = 0; + } + + int[] minC = counter.getMinColour(); + int[] maxC = counter.getMaxColour(); + Color minColour = new Color(minC[0], minC[1], minC[2]); + Color maxColour = new Color(maxC[0], maxC[1], maxC[2]); for (int col = 0; col < width; col++) { - int count = 0; + int[] count = counts[col]; + for (int crow = 0; crow < rows; crow++) + { + count[crow] = 0; + } for (int row = 0; row < height; row++) { - count += countFeaturesAt(alignment, col, row, fr); + int[] colcount = countFeaturesAt(alignment, col, row, fr); + if (colcount != null) + { + for (int crow = 0; crow < rows; crow++) + { + count[crow] += colcount[crow]; + } + } } counts[col] = count; - max = Math.max(count, max); + for (int crow = 0; crow < rows; crow++) + { + max[crow] = Math.max(count[crow], max[crow]); + } } - Annotation[] anns = new Annotation[width]; - /* - * add non-zero counts as annotations - */ - for (int i = 0; i < counts.length; i++) + boolean annotationAdded = false; + + for (int anrow = 0; anrow < rows; anrow++) { - int count = counts[i]; - if (count > 0) + Annotation[] anns = new Annotation[width]; + long rmax = 0; + /* + * add counts as annotations. zeros are needed since select-by-annotation ignores empty annotation positions + */ + for (int i = 0; i < counts.length; i++) { - Color color = ColorUtils.getGraduatedColour(count, 0, Color.cyan, - max, Color.blue); + int count = counts[i][anrow]; + + Color color = ColorUtils.getGraduatedColour(count, 0, minColour, + max[anrow], maxColour); String str = String.valueOf(count); anns[i] = new Annotation(str, str, '0', count, color); + rmax = Math.max(count, rmax); } - } - /* - * construct or update the annotation - */ - AlignmentAnnotation ann = alignViewport.getAlignment() - .findOrCreateAnnotation(counter.getName(), - counter.getDescription(), false, null, null); - ann.description = counter.getDescription(); - ann.showAllColLabels = true; - ann.scaleColLabel = true; - ann.graph = AlignmentAnnotation.BAR_GRAPH; - ann.annotations = anns; - setGraphMinMax(ann, anns); - ann.validateRangeAndDisplay(); - if (!ourAnnots.contains(ann)) - { - ourAnnots.add(ann); + /* + * construct or update the annotation + */ + String description = counter.getDescriptions()[anrow]; + if (!alignment.findAnnotation(description).iterator().hasNext()) + { + annotationAdded = true; + } + AlignmentAnnotation ann = alignment.findOrCreateAnnotation( + counter.getNames()[anrow], description, false, null, null); + ann.description = description; + ann.showAllColLabels = true; + ann.scaleColLabel = true; + ann.graph = AlignmentAnnotation.BAR_GRAPH; + ann.annotations = anns; + ann.graphMin = 0f; // minimum always zero count + ann.graphMax = rmax; // maximum count from loop over feature columns + ann.validateRangeAndDisplay(); + if (!ourAnnots.contains(ann)) + { + ourAnnots.add(ann); + } } + return annotationAdded; } /** @@ -188,35 +229,34 @@ class ColumnCounterWorker extends AlignCalcWorker * * @param alignment * @param col + * (0..) * @param row * @param fr */ - int countFeaturesAt(AlignmentI alignment, int col, int row, + int[] countFeaturesAt(AlignmentI alignment, int col, int row, FeatureRenderer fr) { SequenceI seq = alignment.getSequenceAt(row); if (seq == null) { - return 0; + return null; } if (col >= seq.getLength()) { - return 0;// sequence doesn't extend this far + return null;// sequence doesn't extend this far } char res = seq.getCharAt(col); if (Comparison.isGap(res)) { - return 0; + return null; } - int pos = seq.findPosition(col); /* * compute a count for any displayed features at residue */ - // NB have to adjust pos if using AlignmentView.getVisibleAlignment // see JAL-2075 - List features = fr.findFeaturesAtRes(seq, pos); - int count = this.counter.count(String.valueOf(res), features); + List features = fr.findFeaturesAtColumn(seq, col + 1); + int[] count = this.counter.count(String.valueOf(res), features); return count; }