import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentOrder;
import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SearchResultMatchI;
import jalview.datamodel.SearchResults;
-import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.SearchResultsI;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
/*
* Determine all mappings from this position to mapped sequences.
*/
- SearchResults sr = buildSearchResults(seq, seqpos, mappings);
+ SearchResultsI sr = buildSearchResults(seq, seqpos, mappings);
if (!sr.isEmpty())
{
* @param seqmappings
* @return
*/
- public static SearchResults buildSearchResults(SequenceI seq, int index,
+ public static SearchResultsI buildSearchResults(SequenceI seq, int index,
List<AlignedCodonFrame> seqmappings)
{
- SearchResults results = new SearchResults();
+ SearchResultsI results = new SearchResults();
addSearchResults(results, seq, index, seqmappings);
return results;
}
* @param index
* @param seqmappings
*/
- public static void addSearchResults(SearchResults results, SequenceI seq,
+ public static void addSearchResults(SearchResultsI results, SequenceI seq,
int index, List<AlignedCodonFrame> seqmappings)
{
if (index >= seq.getStart() && index <= seq.getEnd())
* Copy group name, colours etc, but not sequences or sequence colour scheme
*/
SequenceGroup mappedGroup = new SequenceGroup(sg);
- mappedGroup.cs = mapTo.getGlobalColourScheme();
+ mappedGroup.setColourScheme(mapTo.getGlobalColourScheme());
mappedGroup.clear();
int minStartCol = -1;
/*
* Found a sequence mapping. Locate the start/end mapped residues.
*/
- List<AlignedCodonFrame> mapping = Arrays.asList(new AlignedCodonFrame[] { acf });
- SearchResults sr = buildSearchResults(selected,
+ List<AlignedCodonFrame> mapping = Arrays
+ .asList(new AlignedCodonFrame[] { acf });
+ SearchResultsI sr = buildSearchResults(selected,
startResiduePos, mapping);
- for (Match m : sr.getResults())
+ for (SearchResultMatchI m : sr.getResults())
{
mappedStartResidue = m.getStart();
mappedEndResidue = m.getEnd();
}
sr = buildSearchResults(selected, endResiduePos, mapping);
- for (Match m : sr.getResults())
+ for (SearchResultMatchI m : sr.getResults())
{
mappedStartResidue = Math.min(mappedStartResidue,
m.getStart());
* @param fromGapChar
*/
protected static void mapHiddenColumns(int[] hidden,
- List<AlignedCodonFrame> mappings,
- ColumnSelection mappedColumns, List<SequenceI> fromSequences,
- List<SequenceI> toSequences, char fromGapChar)
+ List<AlignedCodonFrame> mappings, ColumnSelection mappedColumns,
+ List<SequenceI> fromSequences, List<SequenceI> toSequences,
+ char fromGapChar)
{
for (int col = hidden[0]; col <= hidden[1]; col++)
{
* @param fromGapChar
*/
protected static void mapColumn(int col,
- List<AlignedCodonFrame> mappings,
- ColumnSelection mappedColumns, List<SequenceI> fromSequences,
- List<SequenceI> toSequences, char fromGapChar)
+ List<AlignedCodonFrame> mappings, ColumnSelection mappedColumns,
+ List<SequenceI> fromSequences, List<SequenceI> toSequences,
+ char fromGapChar)
{
int[] mappedTo = findMappedColumns(col, mappings, fromSequences,
toSequences, fromGapChar);
* Get the residue position and find the mapped position.
*/
int residuePos = fromSeq.findPosition(col);
- SearchResults sr = buildSearchResults(fromSeq, residuePos,
- mappings);
- for (Match m : sr.getResults())
+ SearchResultsI sr = buildSearchResults(fromSeq, residuePos, mappings);
+ for (SearchResultMatchI m : sr.getResults())
{
int mappedStartResidue = m.getStart();
int mappedEndResidue = m.getEnd();
public static List<AlignedCodonFrame> findMappingsForSequence(
SequenceI sequence, List<AlignedCodonFrame> mappings)
{
+ return findMappingsForSequenceAndOthers(sequence, mappings, null);
+ }
+
+ /**
+ * Returns a list of any mappings that are from or to the given (aligned or
+ * dataset) sequence, optionally limited to mappings involving one of a given
+ * list of sequences.
+ *
+ * @param sequence
+ * @param mappings
+ * @param filterList
+ * @return
+ */
+ public static List<AlignedCodonFrame> findMappingsForSequenceAndOthers(
+ SequenceI sequence, List<AlignedCodonFrame> mappings,
+ List<SequenceI> filterList)
+ {
List<AlignedCodonFrame> result = new ArrayList<AlignedCodonFrame>();
if (sequence == null || mappings == null)
{
{
if (mapping.involvesSequence(sequence))
{
- result.add(mapping);
+ if (filterList != null)
+ {
+ for (SequenceI otherseq : filterList)
+ {
+ SequenceI otherDataset = otherseq.getDatasetSequence();
+ if (otherseq == sequence
+ || otherseq == sequence.getDatasetSequence()
+ || (otherDataset != null && (otherDataset == sequence || otherDataset == sequence
+ .getDatasetSequence())))
+ {
+ // skip sequences in subset which directly relate to sequence
+ continue;
+ }
+ if (mapping.involvesSequence(otherseq))
+ {
+ // selected a mapping contained in subselect alignment
+ result.add(mapping);
+ break;
+ }
+ }
+ }
+ else
+ {
+ result.add(mapping);
+ }
}
}
return result;
}
/**
- * Remove the last 3 mapped positions from the given ranges
+ * Returns the total length of the supplied ranges, which may be as single
+ * [start, end] or multiple [start, end, start, end ...]
*
* @param ranges
- * @param mappedLength
+ * @return
*/
- public static void unmapStopCodon(List<int[]> ranges,
- int mappedLength)
+ public static int getLength(List<int[]> ranges)
{
- if (mappedLength < 3)
+ if (ranges == null)
{
- return;
+ return 0;
}
- boolean done = false;
- int targetLength = mappedLength - 3;
- int mapped = 0;
- Iterator<int[]> it = ranges.iterator();
- while (!done && it.hasNext())
+ int length = 0;
+ for (int[] range : ranges)
{
- int[] range = it.next();
- int length = Math.abs(range[1] - range[0]) + 1;
- if (mapped + length == targetLength)
+ if (range.length % 2 != 0)
{
- done = true;
+ System.err.println("Error unbalance start/end ranges: "
+ + ranges.toString());
+ return 0;
}
- else if (mapped + length < targetLength)
+ for (int i = 0; i < range.length - 1; i += 2)
{
- mapped += length;
- continue;
+ length += Math.abs(range[i + 1] - range[i]) + 1;
}
- else
+ }
+ return length;
+ }
+
+ /**
+ * Answers true if any range includes the given value
+ *
+ * @param ranges
+ * @param value
+ * @return
+ */
+ public static boolean contains(List<int[]> ranges, int value)
+ {
+ if (ranges == null)
+ {
+ return false;
+ }
+ for (int[] range : ranges)
+ {
+ if (range[1] >= range[0] && value >= range[0] && value <= range[1])
{
/*
- * need just a bit of this range
+ * value within ascending range
*/
- int needed = targetLength - mapped;
- int sense = range[1] >= range[0] ? 1 : -1;
- range[1] = range[0] + (sense * (needed - 1));
- done = true;
+ return true;
+ }
+ if (range[1] < range[0] && value <= range[0] && value >= range[1])
+ {
+ /*
+ * value within descending range
+ */
+ return true;
}
}
- /*
- * remove any trailing ranges
- */
- while (it.hasNext())
+ return false;
+ }
+
+ /**
+ * Removes a specified number of positions from the start of a ranges list.
+ * For example, could be used to adjust cds ranges to allow for an incomplete
+ * start codon. Subranges are removed completely, or their start positions
+ * adjusted, until the required number of positions has been removed from the
+ * range. Reverse strand ranges are supported. The input array is not
+ * modified.
+ *
+ * @param removeCount
+ * @param ranges
+ * an array of [start, end, start, end...] positions
+ * @return a new array with the first removeCount positions removed
+ */
+ public static int[] removeStartPositions(int removeCount,
+ final int[] ranges)
+ {
+ if (removeCount <= 0)
+ {
+ return ranges;
+ }
+
+ int[] copy = Arrays.copyOf(ranges, ranges.length);
+ int sxpos = -1;
+ int cdspos = 0;
+ for (int x = 0; x < copy.length && sxpos == -1; x += 2)
{
- it.next();
- it.remove();
+ cdspos += Math.abs(copy[x + 1] - copy[x]) + 1;
+ if (removeCount < cdspos)
+ {
+ /*
+ * we have removed enough, time to finish
+ */
+ sxpos = x;
+
+ /*
+ * increment start of first exon, or decrement if reverse strand
+ */
+ if (copy[x] <= copy[x + 1])
+ {
+ copy[x] = copy[x + 1] - cdspos + removeCount + 1;
+ }
+ else
+ {
+ copy[x] = copy[x + 1] + cdspos - removeCount - 1;
+ }
+ break;
+ }
+ }
+
+ if (sxpos > 0)
+ {
+ /*
+ * we dropped at least one entire sub-range - compact the array
+ */
+ int[] nxon = new int[copy.length - sxpos];
+ System.arraycopy(copy, sxpos, nxon, 0, copy.length - sxpos);
+ return nxon;
}
+ return copy;
}
}