-
- /**
- * mark the columns corresponding to gap characters as hidden in the column
- * selection
- *
- * @param sr
- */
- public void hideInsertionsFor(SequenceI sr)
- {
- try
- {
- LOCK.writeLock().lock();
- List<int[]> inserts = sr.getInsertions();
- for (int[] r : inserts)
- {
- hideColumns(r[0], r[1]);
- }
- } finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
- * Unhides, and adds to the selection list, all hidden columns
- */
- public void revealAllHiddenColumns(ColumnSelection sel)
- {
- try
- {
- LOCK.writeLock().lock();
- if (hiddenColumns != null)
- {
- for (int i = 0; i < hiddenColumns.size(); i++)
- {
- int[] region = hiddenColumns.get(i);
- for (int j = region[0]; j < region[1] + 1; j++)
- {
- sel.addElement(j);
- }
- }
- }
-
- hiddenColumns = null;
- } finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
- * Reveals, and marks as selected, the hidden column range with the given
- * start column
- *
- * @param start
- */
- public void revealHiddenColumns(int start, ColumnSelection sel)
- {
- try
- {
- LOCK.writeLock().lock();
- for (int i = 0; i < hiddenColumns.size(); i++)
- {
- int[] region = hiddenColumns.get(i);
- if (start == region[0])
- {
- for (int j = region[0]; j < region[1] + 1; j++)
- {
- sel.addElement(j);
- }
-
- hiddenColumns.remove(region);
- break;
- }
- }
- if (hiddenColumns.size() == 0)
- {
- hiddenColumns = null;
- }
- } finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
- * removes intersection of position,length ranges in deletions from the
- * start,end regions marked in intervals.
- *
- * @param shifts
- * @param intervals
- * @return
- */
- private boolean pruneIntervalList(final List<int[]> shifts,
- ArrayList<int[]> intervals)
- {
- boolean pruned = false;
- int i = 0;
- int j = intervals.size() - 1;
- int s = 0;
- int t = shifts.size() - 1;
- int[] hr = intervals.get(i);
- int[] sr = shifts.get(s);
- while (i <= j && s <= t)
- {
- boolean trailinghn = hr[1] >= sr[0];
- if (!trailinghn)
- {
- if (i < j)
- {
- hr = intervals.get(++i);
- }
- else
- {
- i++;
- }
- continue;
- }
- int endshift = sr[0] + sr[1]; // deletion ranges - -ve means an insert
- if (endshift < hr[0] || endshift < sr[0])
- { // leadinghc disjoint or not a deletion
- if (s < t)
- {
- sr = shifts.get(++s);
- }
- else
- {
- s++;
- }
- continue;
- }
- boolean leadinghn = hr[0] >= sr[0];
- boolean leadinghc = hr[0] < endshift;
- boolean trailinghc = hr[1] < endshift;
- if (leadinghn)
- {
- if (trailinghc)
- { // deleted hidden region.
- intervals.remove(i);
- pruned = true;
- j--;
- if (i <= j)
- {
- hr = intervals.get(i);
- }
- continue;
- }
- if (leadinghc)
- {
- hr[0] = endshift; // clip c terminal region
- leadinghn = !leadinghn;
- pruned = true;
- }
- }
- if (!leadinghn)
- {
- if (trailinghc)
- {
- if (trailinghn)
- {
- hr[1] = sr[0] - 1;
- pruned = true;
- }
- }
- else
- {
- // sr contained in hr
- if (s < t)
- {
- sr = shifts.get(++s);
- }
- else
- {
- s++;
- }
- continue;
- }
- }
- }
- return pruned; // true if any interval was removed or modified by
- // operations.
- }
-
- /**
- * remove any hiddenColumns or selected columns and shift remaining based on a
- * series of position, range deletions.
- *
- * @param deletions
- */
- public void pruneDeletions(List<int[]> shifts)
- {
- try
- {
- LOCK.writeLock().lock();
- // delete any intervals intersecting.
- if (hiddenColumns != null)
- {
- pruneIntervalList(shifts, hiddenColumns);
- if (hiddenColumns != null && hiddenColumns.size() == 0)
- {
- hiddenColumns = null;
- }
- }
- } finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
- * 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 HiddenColumns for new alignment view, with insertions into
- * profileseq marked as hidden.
- */
- public static HiddenColumns propagateInsertions(SequenceI profileseq,
- AlignmentI al, AlignmentView input)
- {
- int profsqpos = 0;
-
- char gc = al.getGapCharacter();
- Object[] alandhidden = input.getAlignmentAndHiddenColumns(gc);
- HiddenColumns nview = (HiddenColumns) alandhidden[1];
- SequenceI origseq = ((SequenceI[]) alandhidden[0])[profsqpos];
- nview.propagateInsertions(profileseq, al, origseq);
- return nview;
- }
-
- /**
- *
- * @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
- */
- private void propagateInsertions(SequenceI profileseq, AlignmentI al,
- SequenceI origseq)
- {
- char gc = al.getGapCharacter();
- // recover mapping between sequence's non-gap positions and positions
- // mapping to view.
- pruneDeletions(ShiftList.parseMap(origseq.gapMap()));
- int[] viscontigs = 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())
- {
- // 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++)
- {
- SequenceI sqobj = al.getSequenceAt(s);
- if (sqobj == profileseq)
- {
- continue;
- }
- String sq = sqobj.getSequenceAsString();
- // pad sequence
- int diff = origseq.getLength() - sq.length();
- while (diff > 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();
- }
- diff = origseq.getLength() - sq.length();
- }
- }
- }
- }
-
- /**
- * 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<int[]> shifts = deletions.getShifts();
- if (shifts != null && shifts.size() > 0)
- {
- pruneDeletions(shifts);
-
- // and shift the rest.
- this.compensateForEdits(deletions);
- }
- }
- }
-
- /**
- * 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<int[]> 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;
- }
-
- /**
- * Returns a hashCode built from hidden column ranges
- */
- @Override
- public int hashCode()
- {
- try
- {
- LOCK.readLock().lock();
- int hashCode = 1;
- if (hiddenColumns != null)
- {
- for (int[] hidden : hiddenColumns)
- {
- hashCode = 31 * hashCode + hidden[0];
- hashCode = 31 * hashCode + hidden[1];
- }
- }
- return hashCode;
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * Hide columns corresponding to the marked bits
- *
- * @param inserts
- * - columns map to bits starting from zero
- */
- public void hideMarkedBits(BitSet inserts)
- {
- try
- {
- LOCK.writeLock().lock();
- for (int firstSet = inserts
- .nextSetBit(0), lastSet = 0; firstSet >= 0; firstSet = inserts
- .nextSetBit(lastSet))
- {
- lastSet = inserts.nextClearBit(firstSet);
- hideColumns(firstSet, lastSet - 1);
- }
- } finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
- *
- * @param inserts
- * BitSet where hidden columns will be marked
- */
- public void markHiddenRegions(BitSet inserts)
- {
- try
- {
- LOCK.readLock().lock();
- if (hiddenColumns == null)
- {
- return;
- }
- for (int[] range : hiddenColumns)
- {
- inserts.set(range[0], range[1] + 1);
- }
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * Calculate the visible start and end index of an alignment.
- *
- * @param width
- * full alignment width
- * @return integer array where: int[0] = startIndex, and int[1] = endIndex
- */
- public int[] getVisibleStartAndEndIndex(int width)
- {
- try
- {
- LOCK.readLock().lock();
- int[] alignmentStartEnd = new int[] { 0, width - 1 };
- int startPos = alignmentStartEnd[0];
- int endPos = alignmentStartEnd[1];
-
- int[] lowestRange = new int[] { -1, -1 };
- int[] higestRange = new int[] { -1, -1 };
-
- if (hiddenColumns == null)
- {
- return new int[] { startPos, endPos };
- }
-
- for (int[] hiddenCol : hiddenColumns)
- {
- lowestRange = (hiddenCol[0] <= startPos) ? hiddenCol : lowestRange;
- higestRange = (hiddenCol[1] >= endPos) ? hiddenCol : higestRange;
- }
-
- if (lowestRange[0] == -1 && lowestRange[1] == -1)
- {
- startPos = alignmentStartEnd[0];
- }
- else
- {
- startPos = lowestRange[1] + 1;
- }
-
- if (higestRange[0] == -1 && higestRange[1] == -1)
- {
- endPos = alignmentStartEnd[1];
- }
- else
- {
- endPos = higestRange[0] - 1;
- }
- return new int[] { startPos, endPos };
- } finally
- {
- LOCK.readLock().unlock();
- }
-
- }
-
- /**
- * Finds the hidden region (if any) which starts or ends at res
- *
- * @param res
- * visible residue position, unadjusted for hidden columns
- * @return region as [start,end] or null if no matching region is found
- */
- public int[] getRegionWithEdgeAtRes(int res)
- {
- try
- {
- LOCK.readLock().lock();
- int adjres = adjustForHiddenColumns(res);
-
- int[] reveal = null;
- if (hiddenColumns != null)
- {
- for (int[] region : hiddenColumns)
- {
- if (adjres + 1 == region[0] || adjres - 1 == region[1])
- {
- reveal = region;
- break;
- }
- }
- }
- return reveal;
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-