- if (hiddenColumns != null)
- {
- for (int[] region : hiddenColumns)
- {
- if (column >= region[0] && column <= region[1])
- {
- return false;
- }
- }
- }
-
- return true;
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * ColumnSelection
- */
- public HiddenColumns()
- {
- }
-
- /**
- * Copy constructor
- *
- * @param copy
- */
- public HiddenColumns(HiddenColumns copy)
- {
- try
- {
-
- LOCK.readLock().lock();
- if (copy != null)
- {
- if (copy.hiddenColumns != null)
- {
- hiddenColumns = copy.copyHiddenRegions();
- }
- }
- }
- finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- private Vector<int[]> copyHiddenRegions()
- {
- Vector<int[]> copy = new Vector<>(hiddenColumns.size());
- for (int i = 0, j = hiddenColumns.size(); i < j; i++)
- {
- int[] rh;
- int[] cp;
- rh = hiddenColumns.elementAt(i);
- if (rh != null)
- {
- cp = new int[rh.length];
- System.arraycopy(rh, 0, cp, 0, rh.length);
- copy.addElement(cp);
- }
- }
- return copy;
- }
-
- private ArrayList<int[]> copyHiddenRegionsToArrayList()
- {
- ArrayList<int[]> copy = new ArrayList<>(hiddenColumns.size());
- for (int i = 0, j = hiddenColumns.size(); i < j; i++)
- {
- int[] rh;
- int[] cp;
- rh = hiddenColumns.elementAt(i);
- if (rh != null)
- {
- cp = new int[rh.length];
- System.arraycopy(rh, 0, cp, 0, rh.length);
- copy.add(cp);
- }
- }
- return copy;
- }
-
- /**
- * Returns a copy of the vector of hidden regions, as a vector. Before using
- * this method please consider if you really need access to the hidden regions
- * - a new (or existing!) method on HiddenColumns might be more appropriate.
- *
- * @return hidden regions as vector of [start,end] pairs
- */
- public Vector<int[]> getHiddenColumnsCopy()
- {
- try
- {
- LOCK.readLock().lock();
- return copyHiddenRegions();
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * Returns a copy of the vector of hidden regions, as an ArrayList. Before
- * using this method please consider if you really need access to the hidden
- * regions - a new (or existing!) method on HiddenColumns might be more
- * appropriate.
- *
- * @return hidden regions as an ArrayList of [start,end] pairs
- */
- public ArrayList<int[]> getHiddenColumnsCopyAsList()
- {
- try
- {
- LOCK.readLock().lock();
- return copyHiddenRegionsToArrayList();
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * 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<int[]> compensateForEdit(int start, int change,
- ColumnSelection sel)
- {
- try
- {
- LOCK.writeLock().lock();
- List<int[]> deletedHiddenColumns = null;
-
- if (hiddenColumns != null)
- {
- deletedHiddenColumns = new ArrayList<>();
- int hSize = hiddenColumns.size();
- for (int i = 0; i < hSize; i++)
- {
- int[] region = hiddenColumns.elementAt(i);
- if (region[0] > start && start + change > region[1])
- {
- deletedHiddenColumns.add(region);
-
- hiddenColumns.removeElementAt(i);
- i--;
- hSize--;
- continue;
- }
-
- if (region[0] > start)
- {
- region[0] -= change;
- region[1] -= change;
- }
-
- if (region[0] < 0)
- {
- region[0] = 0;
- }
-
- }
-
- this.revealHiddenColumns(0, sel);
- }
-
- return deletedHiddenColumns;
- } finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
- * 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)
- */
- public void compensateForDelEdits(int start, int change)
- {
- try
- {
- LOCK.writeLock().lock();
- if (hiddenColumns != null)
- {
- for (int i = 0; i < hiddenColumns.size(); i++)
- {
- int[] region = hiddenColumns.elementAt(i);
- if (region[0] >= start)
- {
- region[0] -= change;
- }
- if (region[1] >= start)
- {
- region[1] -= change;
- }
- if (region[1] < region[0])
- {
- hiddenColumns.removeElementAt(i--);
- }
-
- if (region[0] < 0)
- {
- region[0] = 0;
- }
- if (region[1] < 0)
- {
- region[1] = 0;
- }
- }
- }
- }
- finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
- * return all visible segments between the given start and end boundaries
- *
- * @param start
- * (first column inclusive from 0)
- * @param end
- * (last column - not inclusive)
- * @return int[] {i_start, i_end, ..} where intervals lie in
- * start<=i_start<=i_end<end
- */
- public int[] getVisibleContigs(int start, int end)
- {
- try
- {
- LOCK.readLock().lock();
- if (hiddenColumns != null && hiddenColumns.size() > 0)
- {
- List<int[]> visiblecontigs = new ArrayList<>();
- List<int[]> regions = getHiddenRegions();
-
- int vstart = start;
- int[] region;
- int hideStart;
- int hideEnd;
-
- for (int j = 0; vstart < end && j < regions.size(); j++)
- {
- region = regions.get(j);
- hideStart = region[0];
- hideEnd = region[1];
-
- if (hideEnd < vstart)
- {
- continue;
- }
- if (hideStart > vstart)
- {
- visiblecontigs.add(new int[] { vstart, hideStart - 1 });
- }
- vstart = hideEnd + 1;
- }
-
- if (vstart < end)
- {
- visiblecontigs.add(new int[] { vstart, end - 1 });
- }
- int[] vcontigs = new int[visiblecontigs.size() * 2];
- for (int i = 0, j = visiblecontigs.size(); i < j; i++)
- {
- int[] vc = visiblecontigs.get(i);
- visiblecontigs.set(i, null);
- vcontigs[i * 2] = vc[0];
- vcontigs[i * 2 + 1] = vc[1];
- }
- visiblecontigs.clear();
- return vcontigs;
- }
- else
- {
- return new int[] { start, end - 1 };
- }
- }
- finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- public String[] getVisibleSequenceStrings(int start, int end,
- SequenceI[] seqs)
- {
- try
- {
- LOCK.readLock().lock();
- int iSize = seqs.length;
- String selections[] = new String[iSize];
- if (hiddenColumns != null && hiddenColumns.size() > 0)
- {
- for (int i = 0; i < iSize; i++)
- {
- StringBuffer visibleSeq = new StringBuffer();
- List<int[]> regions = getHiddenRegions();
-
- int blockStart = start;
- int blockEnd = end;
- int[] region;
- int hideStart;
- int hideEnd;
-
- for (int j = 0; j < regions.size(); j++)
- {
- region = regions.get(j);
- hideStart = region[0];
- hideEnd = region[1];
-
- if (hideStart < start)
- {
- continue;
- }
-
- blockStart = Math.min(blockStart, hideEnd + 1);
- blockEnd = Math.min(blockEnd, hideStart);
-
- if (blockStart > blockEnd)
- {
- break;
- }
-
- visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd));
-
- blockStart = hideEnd + 1;
- blockEnd = end;
- }
-
- if (end > blockStart)
- {
- visibleSeq.append(seqs[i].getSequence(blockStart, end));
- }
-
- selections[i] = visibleSeq.toString();
- }
- }
- else
- {
- for (int i = 0; i < iSize; i++)
- {
- selections[i] = seqs[i].getSequenceAsString(start, end);
- }
- }
-
- return selections;
- }
- finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * Locate the first and last position visible for this sequence. if seq isn't
- * visible then return the position of the left and right of the hidden
- * boundary region, and the corresponding alignment column indices for the
- * extent of the sequence
- *
- * @param seq
- * @return int[] { visible start, visible end, first seqpos, last seqpos,
- * alignment index for seq start, alignment index for seq end }
- */
- public int[] locateVisibleBoundsOfSequence(SequenceI seq)
- {
- try
- {
- LOCK.readLock().lock();
- int fpos = seq.getStart();
- int lpos = seq.getEnd();
- int start = 0;
-
- if (hiddenColumns == null || hiddenColumns.size() == 0)
- {
- int ifpos = seq.findIndex(fpos) - 1;
- int ilpos = seq.findIndex(lpos) - 1;
- return new int[] { ifpos, ilpos, fpos, lpos, ifpos, ilpos };
- }
-
- // Simply walk along the sequence whilst watching for hidden column
- // boundaries
- List<int[]> regions = getHiddenRegions();
- int spos = fpos;
- int lastvispos = -1;
- int rcount = 0;
- int hideStart = seq.getLength();
- int hideEnd = -1;
- int visPrev = 0;
- int visNext = 0;
- int firstP = -1;
- int lastP = -1;
- boolean foundStart = false;
- for (int p = 0, pLen = seq.getLength(); spos <= seq.getEnd()
- && p < pLen; p++)