- * Output regions data as a string. String is in the format:
- * reg0[0]<between>reg0[1]<delimiter>reg1[0]<between>reg1[1] ... regn[1]
- *
- * @param delimiter
- * string to delimit regions
- * @param betweenstring
- * to put between start and end region values
- * @return regions formatted according to delimiter and between strings
- */
- public String regionsToString(String delimiter, String between)
- {
- try
- {
- LOCK.readLock().lock();
- StringBuilder regionBuilder = new StringBuilder();
- if (hiddenColumns != null)
- {
- Iterator<int[]> it = hiddenColumns.iterator();
- while (it.hasNext())
- {
- int[] range = it.next();
- regionBuilder.append(delimiter).append(range[0]).append(between)
- .append(range[1]);
- if (!it.hasNext())
- {
- regionBuilder.deleteCharAt(0);
- }
- }
- }
- return regionBuilder.toString();
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * Find the number of hidden columns
- *
- * @return number of hidden columns
- */
- public int getSize()
- {
- try
- {
- LOCK.readLock().lock();
- int size = 0;
- if (hiddenColumns != null)
- {
- Iterator<int[]> it = hiddenColumns.iterator();
- while (it.hasNext())
- {
- int[] range = it.next();
- size += range[1] - range[0] + 1;
- }
- }
- return size;
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * Get the number of distinct hidden regions
- *
- * @return number of regions
- */
- public int getNumberOfRegions()
- {
- try
- {
- LOCK.readLock().lock();
- int num = 0;
- if (hasHiddenColumns())
- {
- num = hiddenColumns.size();
- }
- return num;
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- @Override
- public boolean equals(Object obj)
- {
- try
- {
- LOCK.readLock().lock();
-
- if (!(obj instanceof HiddenColumns))
- {
- return false;
- }
- HiddenColumns that = (HiddenColumns) obj;
-
- /*
- * check hidden columns are either both null, or match
- */
- if (this.hiddenColumns == null)
- {
- return (that.hiddenColumns == null);
- }
- if (that.hiddenColumns == null
- || that.hiddenColumns.size() != this.hiddenColumns.size())
- {
- return false;
- }
-
- Iterator<int[]> it = hiddenColumns.iterator();
- Iterator<int[]> thatit = that.iterator();
- while (it.hasNext())
- {
- int[] thisRange = it.next();
- int[] thatRange = thatit.next();
- if (thisRange[0] != thatRange[0] || thisRange[1] != thatRange[1])
- {
- return false;
- }
- }
- return true;
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * Return absolute column index for a visible column index
- *
- * @param column
- * int column index in alignment view (count from zero)
- * @return alignment column index for column
- */
- public int adjustForHiddenColumns(int column)
- {
- try
- {
- LOCK.readLock().lock();
- int result = column;
-
- if (hiddenColumns != null)
- {
- result += cursor.getHiddenOffset(column);
-
-
- /*Iterator<int[]> it = hiddenColumns.iterator();
- while (it.hasNext())
- {
- int[] region = it.next();
- if (result >= region[0])
- {
- result += region[1] - region[0] + 1;
- }
- }*/
- }
-
- return result;
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * Use this method to find out where a column will appear in the visible
- * alignment when hidden columns exist. If the column is not visible, then the
- * left-most visible column will always be returned.
- *
- * @param hiddenColumn
- * the column index in the full alignment including hidden columns
- * @return the position of the column in the visible alignment
- */
- public int findColumnPosition(int hiddenColumn)
- {
- try
- {
- LOCK.readLock().lock();
- int result = hiddenColumn;
- int[] region = null;
- if (hiddenColumns != null)
- {
- Iterator<int[]> it = new RegionsIterator(0,
- hiddenColumn, hiddenColumns, cursor);
- while (it.hasNext())
- {
- region = it.next();
- if (hiddenColumn > region[1])
- {
- result -= region[1] + 1 - region[0];
- }
- }
-
- if (region != null && hiddenColumn >= region[0]
- && hiddenColumn <= region[1])
- {
- // Here the hidden column is within a region, so
- // we want to return the position of region[0]-1, adjusted for any
- // earlier hidden columns.
- // Calculate the difference between the actual hidden col position
- // and region[0]-1, and then subtract from result to convert result
- // from the adjusted hiddenColumn value to the adjusted region[0]-1
- // value.
-
- // However, if the region begins at 0 we cannot return region[0]-1
- // just return 0
- if (region[0] == 0)
- {
- return 0;
- }
- else
- {
- return result - (hiddenColumn - region[0] + 1);
- }
- }
- }
- return result; // return the shifted position after removing hidden
- // columns.
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * Find the visible column which is a given visible number of columns to the
- * left of another visible column. i.e. for a startColumn x, the column which
- * is distance 1 away will be column x-1.
- *
- * @param visibleDistance
- * the number of visible columns to offset by
- * @param startColumn
- * the column to start from
- * @return the position of the column in the visible alignment
- */
- public int subtractVisibleColumns(int visibleDistance, int startColumn)
- {
- try
- {
- LOCK.readLock().lock();
- int distance = visibleDistance;
-
- // in case startColumn is in a hidden region, move it to the left
- int start = adjustForHiddenColumns(findColumnPosition(startColumn));
-
- Iterator<int[]> it = new ReverseRegionsIterator(0, start,
- hiddenColumns);
-
- while (it.hasNext() && (distance > 0))
- {
- int[] region = it.next();
-
- if (start > region[1])
- {
- // subtract the gap to right of region from distance
- if (start - region[1] <= distance)
- {
- distance -= start - region[1];
- start = region[0] - 1;
- }
- else
- {
- start = start - distance;
- distance = 0;
- }
- }
- }
-
- return start - distance;
-
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * This method returns the rightmost limit of a region of an alignment with
- * hidden columns. In otherwords, the next hidden column.
- *
- * @param alPos
- * the (visible) alignmentPosition to find the next hidden column for
- */
- public int getHiddenBoundaryRight(int alPos)
- {
- try
- {
- LOCK.readLock().lock();
- if (hiddenColumns != null)
- {
- Iterator<int[]> it = hiddenColumns.iterator();
- while (it.hasNext())
- {
- int[] region = it.next();
- if (alPos < region[0])
- {
- return region[0];
- }
- }
- }
- return alPos;
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * This method returns the leftmost limit of a region of an alignment with
- * hidden columns. In otherwords, the previous hidden column.
- *
- * @param alPos
- * the (visible) alignmentPosition to find the previous hidden column
- * for
- */
- public int getHiddenBoundaryLeft(int alPos)
- {
- try
- {
- LOCK.readLock().lock();
-
- Iterator<int[]> it = new ReverseRegionsIterator(0, alPos,
- hiddenColumns);
- while (it.hasNext())
- {
- int[] region = it.next();
- if (alPos > region[1])
- {
- return region[1];
- }
- }
-
- return alPos;
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**