public int[] getMappedPositions(int begin, int end)
{
MapList map = mapping.getMap();
- return mapping.to == featureSequence ? map.locateInFrom(begin, end)
- : map.locateInTo(begin, end);
+ return mapping.to == featureSequence ? map.getOverlapsInFrom(begin, end)
+ : map.getOverlapsInTo(begin, end);
}
/**
String consequence = "";
if (mf != null)
{
- int[] beginRange = mf.getMappedPositions(begin, begin);
- int[] endRange = mf.getMappedPositions(end, end);
- int from = beginRange[0];
- int to = endRange[endRange.length - 1];
+ int[] localRange = mf.getMappedPositions(begin, end);
+ int from = localRange[0];
+ int to = localRange[localRange.length - 1];
String s = mf.isFromCds() ? "Peptide Location" : "Coding location";
sb.append(String.format(ROW_DATA, s, seqName, from == to ? from
: from + (isContactFeature() ? ":" : "-") + to));
/*
* show local rather than linked feature coordinates
*/
- int[] beginRange = mf.getMappedPositions(start, start);
- int[] endRange = mf.getMappedPositions(end, end);
- if (beginRange == null || endRange == null)
+ int[] localRange = mf.getMappedPositions(start, end);
+ if (localRange == null)
{
// e.g. variant extending to stop codon so not mappable
return;
}
- start = beginRange[0];
- end = endRange[endRange.length - 1];
+ start = localRange[0];
+ end = localRange[localRange.length - 1];
}
StringBuilder desc = new StringBuilder();
desc.append(sf.getType()).append(" ").append(String.valueOf(start));
* if this is a virtual features, convert begin/end to the
* coordinates of the sequence it is mapped to
*/
- int[] beginRange = null;
- int[] endRange = null;
+ int[] beginRange = null; // feature start in local coordinates
+ int[] endRange = null; // feature end in local coordinates
if (mf != null)
{
- beginRange = mf.getMappedPositions(begin, begin);
- endRange = mf.getMappedPositions(end, end);
+ if (feature.isContactFeature())
+ {
+ /*
+ * map start and end points individually
+ */
+ beginRange = mf.getMappedPositions(begin, begin);
+ endRange = begin == end ? beginRange
+ : mf.getMappedPositions(end, end);
+ }
+ else
+ {
+ /*
+ * map the feature extent
+ */
+ beginRange = mf.getMappedPositions(begin, end);
+ endRange = beginRange;
+ }
if (beginRange == null || endRange == null)
{
// something went wrong
import java.util.BitSet;
import java.util.List;
+import jalview.bin.Cache;
+
/**
* A simple way of bijectively mapping a non-contiguous linear range to another
* non-contiguous linear range.
if (range.length != 2)
{
// throw new IllegalArgumentException(range);
- System.err.println("Invalid format for fromRange "
+ Cache.log.error("Invalid format for fromRange "
+ Arrays.toString(range) + " may cause errors");
}
fromLowest = Math.min(fromLowest, Math.min(range[0], range[1]));
if (range.length != 2)
{
// throw new IllegalArgumentException(range);
- System.err.println("Invalid format for toRange "
+ Cache.log.error("Invalid format for toRange "
+ Arrays.toString(range) + " may cause errors");
}
toLowest = Math.min(toLowest, Math.min(range[0], range[1]));
int mp[][] = new int[to - from + 2][];
for (int i = 0; i < mp.length; i++)
{
- int[] m = shift(i + from, shiftTo, sourceRatio, shiftFrom, targetRatio);
+ int[] m = shift(i + from, shiftTo, sourceRatio, shiftFrom,
+ targetRatio);
if (m != null)
{
if (i == 0)
}
/**
- * Returns the [start1, end1, start2, end2, ...] positions in the 'from' range
- * that map to positions between {@code start} and {@code end} in the 'to'
- * range. Note that for a reverse strand mapping this will return ranges with
- * end < start. Returns null if no mapped positions are found in start-end.
+ * <<<<<<< HEAD Returns the [start1, end1, start2, end2, ...] positions in the
+ * 'from' range that map to positions between {@code start} and {@code end} in
+ * the 'to' range. Note that for a reverse strand mapping this will return
+ * ranges with end < start. Returns null if no mapped positions are found in
+ * start-end.
*
* @param start
* @param end
*/
public int[] locateInFrom(int start, int end)
{
- return mapPositions(start, end, toShifts, fromShifts,
- toRatio, fromRatio);
+ return mapPositions(start, end, toShifts, fromShifts, toRatio,
+ fromRatio);
}
/**
*/
public int[] locateInTo(int start, int end)
{
- return mapPositions(start, end, fromShifts, toShifts,
- fromRatio, toRatio);
+ return mapPositions(start, end, fromShifts, toShifts, fromRatio,
+ toRatio);
}
/**
* @return
*/
protected final static BitSet getMappedOffsetsForPositions(int start,
- int end, List<int[]> sourceRange, int sourceWordLength, int targetWordLength)
+ int end, List<int[]> sourceRange, int sourceWordLength,
+ int targetWordLength)
{
BitSet overlaps = new BitSet();
int offset = 0;
return added;
}
+
+ /*
+ * Returns the [start, end...] positions in the range mapped from, that are
+ * mapped to by part or all of the given begin-end of the range mapped to.
+ * Returns null if begin-end does not overlap any position mapped to.
+ *
+ * @param begin
+ * @param end
+ * @return
+ */
+ public int[] getOverlapsInFrom(final int begin, final int end)
+ {
+ int[] overlaps = MappingUtils.findOverlap(toShifts, begin, end);
+
+ return overlaps == null ? null : locateInFrom(overlaps[0], overlaps[1]);
+ }
+
+ /**
+ * Returns the [start, end...] positions in the range mapped to, that are
+ * mapped to by part or all of the given begin-end of the range mapped from.
+ * Returns null if begin-end does not overlap any position mapped from.
+ *
+ * @param begin
+ * @param end
+ * @return
+ */
+ public int[] getOverlapsInTo(final int begin, final int end)
+ {
+ int[] overlaps = MappingUtils.findOverlap(fromShifts, begin, end);
+
+ return overlaps == null ? null : locateInTo(overlaps[0], overlaps[1]);
+ }
}
{
if (range.length % 2 != 0)
{
- System.err.println(
+ Cache.log.error(
"Error unbalance start/end ranges: " + ranges.toString());
return 0;
}
/*
* not coded for [start1, end1, start2, end2, ...]
*/
- System.err.println(
+ Cache.log.error(
"MappingUtils.removeEndPositions doesn't handle multiple ranges");
return;
}
/*
* not coded for a reverse strand range (end < start)
*/
- System.err.println(
+ Cache.log.error(
"MappingUtils.removeEndPositions doesn't handle reverse strand");
return;
}
}
return result;
}
+
+ /*
+ * Returns the maximal start-end positions in the given (ordered) list of
+ * ranges which is overlapped by the given begin-end range, or null if there
+ * is no overlap.
+ *
+ * <pre>
+ * Examples:
+ * if ranges is {[4, 8], [10, 12], [16, 19]}
+ * then
+ * findOverlap(ranges, 1, 20) == [4, 19]
+ * findOverlap(ranges, 6, 11) == [6, 11]
+ * findOverlap(ranges, 9, 15) == [10, 12]
+ * findOverlap(ranges, 13, 15) == null
+ * </pre>
+ *
+ * @param ranges
+ * @param begin
+ * @param end
+ * @return
+ */
+ protected static int[] findOverlap(List<int[]> ranges, final int begin,
+ final int end)
+ {
+ boolean foundStart = false;
+ int from = 0;
+ int to = 0;
+
+ /*
+ * traverse the ranges to find the first position (if any) >= begin,
+ * and the last position (if any) <= end
+ */
+ for (int[] range : ranges)
+ {
+ if (!foundStart)
+ {
+ if (range[0] >= begin)
+ {
+ /*
+ * first range that starts with, or follows, begin
+ */
+ foundStart = true;
+ from = Math.max(range[0], begin);
+ }
+ else if (range[1] >= begin)
+ {
+ /*
+ * first range that contains begin
+ */
+ foundStart = true;
+ from = begin;
+ }
+ }
+
+ if (range[0] <= end)
+ {
+ to = Math.min(end, range[1]);
+ }
+ }
+
+ return foundStart && to >= from ? new int[] { from, to } : null;
+ }
}
*/
package jalview.ws.dbsources;
-import java.util.Locale;
-
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import jalview.xml.binding.embl.ROOT;
import jalview.xml.binding.embl.XrefType;
-/**
- * Provides XML binding and parsing of EMBL or EMBLCDS records retrieved from
- * (e.g.) {@code https://www.ebi.ac.uk/ena/data/view/x53828&display=xml}.
- *
- * @deprecated endpoint withdrawn August 2020 (JAL-3692), use EmblFlatfileSource
- */
public abstract class EmblXmlSource extends EbiFileRetrievedProxy
{
private static final Regex ACCESSION_REGEX = new Regex("^[A-Z]+[0-9]+");
try
{
reply = dbFetch.fetchDataAsFile(
- emprefx.toLowerCase(Locale.ROOT) + ":" + query.trim(), "display=xml",
- "xml");
+ emprefx.toLowerCase(Locale.ROOT) + ":" + query.trim(),
+ "display=xml", "xml");
} catch (Exception e)
{
stopQuery();
else
{
// final product length truncation check
- int[] cdsRanges = adjustForProteinLength(translationLength,
- exons);
- dnaToProteinMapping = new Mapping(product, cdsRanges,
+ int[] exons2 = adjustForProteinLength(translationLength, exons);
+ dnaToProteinMapping = new Mapping(product, exons2,
new int[]
{ 1, translationLength }, 3, 1);
if (product != null)
/**
* Truncates (if necessary) the exon intervals to match 3 times the length of
- * the protein; also accepts 3 bases longer (for stop codon not included in
- * protein)
+ * the protein (including truncation for stop codon included in exon)
*
* @param proteinLength
* @param exon
int exonLength = MappingUtils.getLength(Arrays.asList(exon));
/*
- * if exon length matches protein, or is shorter, or longer by the
- * length of a stop codon (3 bases), then leave it unchanged
+ * if exon length matches protein, or is shorter, then leave it unchanged
*/
- if (expectedCdsLength >= exonLength
- || expectedCdsLength == exonLength - 3)
+ if (expectedCdsLength >= exonLength)
{
return exon;
}
@Test(groups = { "Functional" })
public void testCopyConstructors()
{
- SequenceFeature sf1 = new SequenceFeature("type", "desc", 22, 33,
- 12.5f, "group");
+ SequenceFeature sf1 = new SequenceFeature("type", "desc", 22, 33, 12.5f,
+ "group");
sf1.setValue("STRAND", "+");
sf1.setValue("Note", "Testing");
Integer count = Integer.valueOf(7);
/*
* copy constructor modifying type/begin/end/group/score
*/
- SequenceFeature sf4 = new SequenceFeature(sf1, "Disulfide bond", 12,
- 15, "group3", -9.1f);
+ SequenceFeature sf4 = new SequenceFeature(sf1, "Disulfide bond", 12, 15,
+ "group3", -9.1f);
assertEquals("Disulfide bond", sf4.getType());
assertTrue(sf4.isContactFeature());
assertEquals("desc", sf4.getDescription());
@Test(groups = { "Functional" })
public void testGetValue()
{
- SequenceFeature sf1 = new SequenceFeature("type", "desc", 22, 33,
- 12.5f, "group");
+ SequenceFeature sf1 = new SequenceFeature("type", "desc", 22, 33, 12.5f,
+ "group");
sf1.setValue("STRAND", "+");
assertEquals("+", sf1.getValue("STRAND"));
assertNull(sf1.getValue("strand")); // case-sensitive
@Test(groups = { "Functional" })
public void testEqualsAndHashCode()
{
- SequenceFeature sf1 = new SequenceFeature("type", "desc", 22, 33,
- 12.5f, "group");
+ SequenceFeature sf1 = new SequenceFeature("type", "desc", 22, 33, 12.5f,
+ "group");
sf1.setValue("ID", "id");
sf1.setValue("Name", "name");
sf1.setValue("Parent", "parent");
sf1.setStrand("+");
sf1.setPhase("1");
- SequenceFeature sf2 = new SequenceFeature("type", "desc", 22, 33,
- 12.5f, "group");
+ SequenceFeature sf2 = new SequenceFeature("type", "desc", 22, 33, 12.5f,
+ "group");
sf2.setValue("ID", "id");
sf2.setValue("Name", "name");
sf2.setValue("Parent", "parent");
assertEquals(sf1.hashCode(), sf2.hashCode());
// changing type breaks equals:
- SequenceFeature sf3 = new SequenceFeature("type", "desc", 22, 33,
- 12.5f, "group");
- SequenceFeature sf4 = new SequenceFeature("Type", "desc", 22, 33,
- 12.5f, "group");
+ SequenceFeature sf3 = new SequenceFeature("type", "desc", 22, 33, 12.5f,
+ "group");
+ SequenceFeature sf4 = new SequenceFeature("Type", "desc", 22, 33, 12.5f,
+ "group");
assertFalse(sf3.equals(sf4));
// changing description breaks equals:
// changing start position breaks equals:
int restorei = sf2.getBegin();
- sf2 = new SequenceFeature(sf2, 21, sf2.getEnd(), sf2.getFeatureGroup(), sf2.getScore());
+ sf2 = new SequenceFeature(sf2, 21, sf2.getEnd(), sf2.getFeatureGroup(),
+ sf2.getScore());
assertFalse(sf1.equals(sf2));
sf2 = new SequenceFeature(sf2, restorei, sf2.getEnd(),
sf2.getFeatureGroup(), sf2.getScore());
// changing feature group breaks equals:
restores = sf2.getFeatureGroup();
- sf2 = new SequenceFeature(sf2, sf2.getBegin(), sf2.getEnd(), "Group", sf2.getScore());
+ sf2 = new SequenceFeature(sf2, sf2.getBegin(), sf2.getEnd(), "Group",
+ sf2.getScore());
assertFalse(sf1.equals(sf2));
- sf2 = new SequenceFeature(sf2, sf2.getBegin(), sf2.getEnd(), restores, sf2.getScore());
+ sf2 = new SequenceFeature(sf2, sf2.getBegin(), sf2.getEnd(), restores,
+ sf2.getScore());
// changing ID breaks equals:
restores = (String) sf2.getValue("ID");
String seqName = seq.getName();
// single locus, no group, no score
- SequenceFeature sf = new SequenceFeature("variant", "G,C", 22, 22, null);
+ SequenceFeature sf = new SequenceFeature("variant", "G,C", 22, 22,
+ null);
String expected = "<br><table><tr><td>Location</td><td>TestSeq</td><td>22</td></tr>"
+ "<tr><td>Type</td><td>variant</td><td></td></tr>"
+ "<tr><td>Description</td><td>G,C</td><td></td></tr></table>";
+ "<tr><td>Description</td><td>a description</td><td></td></tr></table>";
assertEquals(expected, sf.getDetailsReport(seqName, null));
- sf = new SequenceFeature("variant", "G,C", 22, 33,
- 12.5f, "group");
+ sf = new SequenceFeature("variant", "G,C", 22, 33, 12.5f, "group");
sf.setValue("Parent", "ENSG001");
sf.setValue("Child", "ENSP002");
expected = "<br><table><tr><td>Location</td><td>TestSeq</td><td>22-33</td></tr>"
+ "<tr><td>Type</td><td>variant</td><td></td></tr>"
+ "<tr><td>Description</td><td>G,C</td><td></td></tr>"
+ "<tr><td>Consequence</td><td><i>Translated by Jalview</i></td><td>p.Leu9Phe</td></tr>"
- + "<tr><td>alleles</td><td></td><td>G,C</td></tr>"
+ + "<tr><td>alleles</td><td></td><td>G,C</td></tr>"
+ "</table>";
assertEquals(expected, sf.getDetailsReport(seq.getName(), mf));
+
+
+ /*
+ * exon feature extending beyond mapped range; mapped location should be
+ * restricted to peptide mapped range limit i.e. 10-13
+ */
+ SequenceFeature sf2 = new SequenceFeature("exon", "exon 1", 109, 230, null);
+ features.add(sf2);
+ expected = "<br><table><tr><td>Location</td><td>Cds</td><td>109-230</td></tr>"
+ + "<tr><td>Peptide Location</td><td>TestSeq</td><td>10-13</td></tr>"
+ + "<tr><td>Type</td><td>exon</td><td></td></tr>"
+ + "<tr><td>Description</td><td>exon 1</td><td></td></tr>"
+ + "</table>";
+ assertEquals(expected, sf2.getDetailsReport(seq.getName(), mf));
}
}
* no overlap
*/
assertNull(ml.locateInFrom(0, 0));
-
+
}
/**
assertEquals("[10, 10, 12, 12, 14, 14]",
Arrays.toString(ml.locateInFrom(3, 3)));
assertEquals("[16, 18]", Arrays.toString(ml.locateInFrom(4, 4)));
-
+
/*
* codons at 11-16, 21-26, 31-36 mapped to peptide positions 1, 3-4, 6-8
*/
}
/**
+ * Tests for method that locates the overlap of the ranges in the 'from' map
+ * for given range in the 'to' map
+ */
+ @Test(groups = { "Functional" })
+ public void testGetOverlapsInFrom_withIntrons()
+ {
+ /*
+ * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e.
+ * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18
+ */
+ int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 };
+ int[] protein = { 11, 14 };
+ MapList ml = new MapList(codons, protein, 3, 1);
+
+ assertEquals("[2, 3, 5, 5]",
+ Arrays.toString(ml.getOverlapsInFrom(11, 11)));
+ assertEquals("[2, 3, 5, 7, 9, 9]",
+ Arrays.toString(ml.getOverlapsInFrom(11, 12)));
+ // out of range 5' :
+ assertEquals("[2, 3, 5, 7, 9, 9]",
+ Arrays.toString(ml.getOverlapsInFrom(8, 12)));
+ // out of range 3' :
+ assertEquals("[10, 10, 12, 12, 14, 14, 16, 18]",
+ Arrays.toString(ml.getOverlapsInFrom(13, 16)));
+ // out of range both :
+ assertEquals("[2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18]",
+ Arrays.toString(ml.getOverlapsInFrom(1, 16)));
+ // no overlap:
+ assertNull(ml.getOverlapsInFrom(20, 25));
+ }
+
+ /**
+ * Tests for method that locates the overlap of the ranges in the 'to' map for
+ * given range in the 'from' map
+ */
+ @Test(groups = { "Functional" })
+ public void testGetOverlapsInTo_withIntrons()
+ {
+ /*
+ * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [17, 18, 19] i.e.
+ * 2-3, 5-7, 9-10, 12-12, 14-14, 17-19
+ */
+ int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 17, 19 };
+ /*
+ * Mapped proteins at positions 1, 3, 4, 6 in the sequence
+ */
+ int[] protein = { 1, 1, 3, 4, 6, 6 };
+ MapList ml = new MapList(codons, protein, 3, 1);
+
+ /*
+ * Can't map from an unmapped position
+ */
+ assertNull(ml.getOverlapsInTo(1, 1));
+ assertNull(ml.getOverlapsInTo(4, 4));
+ assertNull(ml.getOverlapsInTo(15, 16));
+
+ /*
+ * nor from a range that includes no mapped position (exon)
+ */
+ assertNull(ml.getOverlapsInTo(15, 16));
+
+ // end of codon 1 maps to first peptide
+ assertEquals("[1, 1]", Arrays.toString(ml.getOverlapsInTo(2, 2)));
+ // end of codon 1 and start of codon 2 maps to first 2 peptides
+ assertEquals("[1, 1, 3, 3]", Arrays.toString(ml.getOverlapsInTo(3, 7)));
+
+ // range overlaps 5' end of dna:
+ assertEquals("[1, 1, 3, 3]", Arrays.toString(ml.getOverlapsInTo(1, 6)));
+ assertEquals("[1, 1, 3, 3]", Arrays.toString(ml.getOverlapsInTo(1, 8)));
+
+ // range overlaps 3' end of dna:
+ assertEquals("[6, 6]", Arrays.toString(ml.getOverlapsInTo(17, 24)));
+ assertEquals("[6, 6]", Arrays.toString(ml.getOverlapsInTo(16, 24)));
+
+ // dna positions 8, 11 are intron but include end of exon 2 and start of
+ // exon 3
+ assertEquals("[3, 4]", Arrays.toString(ml.getOverlapsInTo(8, 11)));
+ }
+
+ /**
* Tests for method that locates ranges in the 'to' map for given range in the
* 'from' map.
*/
*/
assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(1, 13)));
assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(-1, 2)));
-
+
/*
* no overlap
*/
assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 2)));
assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 4)));
assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 4)));
-
+
/*
* no overlap
*/
toRanges = compound.getToRanges();
assertEquals(2, toRanges.size());
assertArrayEquals(new int[] { 931, 901 }, toRanges.get(0));
- assertArrayEquals(new int[] { 600, 582}, toRanges.get(1));
+ assertArrayEquals(new int[] { 600, 582 }, toRanges.get(1));
/*
* 1:1 plus 1:3 should result in 1:3
* no overlap
*/
assertNull(ml.locateInTo(0, 0));
-
+
/*
* partial overlap
*/
ml = new MapList(gene, cds, 1, 1);
assertEquals("[13203, 13204]",
Arrays.toString(ml.locateInTo(13468, 13468)));
-
+
/*
* gene to protein
* the base at 13468 is in the codon for 4401N and also 4402R
public void testAddOffsetPositions()
{
List<int[]> mapped = new ArrayList<>();
- int[] range = new int[] {10, 20};
+ int[] range = new int[] { 10, 20 };
BitSet offsets = new BitSet();
MapList.addOffsetPositions(mapped, 0, range, offsets);
assertArrayEquals(new int[] { 14, 13 }, mapped.get(1));
assertArrayEquals(new int[] { 10, 10 }, mapped.get(2));
}
-
+
@Test(groups = { "Functional" })
public void testGetPositionsForOffsets()
{
BitSet offsets = new BitSet();
List<int[]> mapped = MapList.getPositionsForOffsets(ranges, offsets);
assertTrue(mapped.isEmpty()); // no ranges and no offsets!
-
+
offsets.set(5, 1000);
mapped = MapList.getPositionsForOffsets(ranges, offsets);
assertTrue(mapped.isEmpty()); // no ranges
-
+
/*
* one range with overlap of offsets
*/
- ranges.add(new int[] {15, 25});
+ ranges.add(new int[] { 15, 25 });
mapped = MapList.getPositionsForOffsets(ranges, offsets);
assertEquals(1, mapped.size());
- assertArrayEquals(new int[] {20, 25}, mapped.get(0));
-
+ assertArrayEquals(new int[] { 20, 25 }, mapped.get(0));
+
/*
* two ranges
*/
- ranges.add(new int[] {300, 320});
+ ranges.add(new int[] { 300, 320 });
mapped = MapList.getPositionsForOffsets(ranges, offsets);
assertEquals(2, mapped.size());
- assertArrayEquals(new int[] {20, 25}, mapped.get(0));
- assertArrayEquals(new int[] {300, 320}, mapped.get(1));
-
+ assertArrayEquals(new int[] { 20, 25 }, mapped.get(0));
+ assertArrayEquals(new int[] { 300, 320 }, mapped.get(1));
+
/*
* boundary case - right end of first range overlaps
*/
offsets.set(10);
mapped = MapList.getPositionsForOffsets(ranges, offsets);
assertEquals(1, mapped.size());
- assertArrayEquals(new int[] {25, 25}, mapped.get(0));
-
+ assertArrayEquals(new int[] { 25, 25 }, mapped.get(0));
+
/*
* boundary case - left end of second range overlaps
*/
offsets.set(11);
mapped = MapList.getPositionsForOffsets(ranges, offsets);
assertEquals(2, mapped.size());
- assertArrayEquals(new int[] {25, 25}, mapped.get(0));
- assertArrayEquals(new int[] {300, 300}, mapped.get(1));
-
+ assertArrayEquals(new int[] { 25, 25 }, mapped.get(0));
+ assertArrayEquals(new int[] { 300, 300 }, mapped.get(1));
+
/*
* offsets into a circular range are reported in
* the order in which they are traversed
*/
ranges.clear();
- ranges.add(new int[] {100, 150});
- ranges.add(new int[] {60, 80});
+ ranges.add(new int[] { 100, 150 });
+ ranges.add(new int[] { 60, 80 });
offsets.clear();
offsets.set(45, 55); // sets bits 45 to 54
mapped = MapList.getPositionsForOffsets(ranges, offsets);
assertEquals(2, mapped.size());
- assertArrayEquals(new int[] {145, 150}, mapped.get(0)); // offsets 45-50
- assertArrayEquals(new int[] {60, 63}, mapped.get(1)); // offsets 51-54
+ assertArrayEquals(new int[] { 145, 150 }, mapped.get(0)); // offsets 45-50
+ assertArrayEquals(new int[] { 60, 63 }, mapped.get(1)); // offsets 51-54
/*
* reverse range overlap is reported with start < end
*/
ranges.clear();
- ranges.add(new int[] {4321, 4000});
+ ranges.add(new int[] { 4321, 4000 });
offsets.clear();
offsets.set(20, 22); // sets bits 20 and 21
offsets.set(30);
mapped = MapList.getPositionsForOffsets(ranges, offsets);
assertEquals(2, mapped.size());
- assertArrayEquals(new int[] {4301, 4300}, mapped.get(0));
- assertArrayEquals(new int[] {4291, 4291}, mapped.get(1));
+ assertArrayEquals(new int[] { 4301, 4300 }, mapped.get(0));
+ assertArrayEquals(new int[] { 4291, 4291 }, mapped.get(1));
}
-
+
@Test(groups = { "Functional" })
public void testGetMappedOffsetsForPositions()
{
* start by verifying the examples in the method's Javadoc!
*/
List<int[]> ranges = new ArrayList<>();
- ranges.add(new int[] {10, 20});
- ranges.add(new int[] {31, 40});
- BitSet overlaps = MapList.getMappedOffsetsForPositions(1, 9, ranges, 1, 1);
+ ranges.add(new int[] { 10, 20 });
+ ranges.add(new int[] { 31, 40 });
+ BitSet overlaps = MapList.getMappedOffsetsForPositions(1, 9, ranges, 1,
+ 1);
assertTrue(overlaps.isEmpty());
overlaps = MapList.getMappedOffsetsForPositions(1, 11, ranges, 1, 1);
assertEquals(2, overlaps.cardinality());
assertTrue(overlaps.get(1));
overlaps = MapList.getMappedOffsetsForPositions(15, 35, ranges, 1, 1);
assertEquals(11, overlaps.cardinality());
- for (int i = 5 ; i <= 11 ; i++)
+ for (int i = 5; i <= 11; i++)
{
assertTrue(overlaps.get(i));
}
-
+
ranges.clear();
- ranges.add(new int[] {1, 200});
+ ranges.add(new int[] { 1, 200 });
overlaps = MapList.getMappedOffsetsForPositions(9, 9, ranges, 1, 3);
assertEquals(3, overlaps.cardinality());
assertTrue(overlaps.get(24));
assertTrue(overlaps.get(25));
assertTrue(overlaps.get(26));
-
+
ranges.clear();
- ranges.add(new int[] {101, 150});
- ranges.add(new int[] {171, 180});
+ ranges.add(new int[] { 101, 150 });
+ ranges.add(new int[] { 171, 180 });
overlaps = MapList.getMappedOffsetsForPositions(101, 102, ranges, 3, 1);
assertEquals(1, overlaps.cardinality());
assertTrue(overlaps.get(0));
overlaps = MapList.getMappedOffsetsForPositions(150, 171, ranges, 3, 1);
assertEquals(1, overlaps.cardinality());
assertTrue(overlaps.get(16));
-
+
ranges.clear();
- ranges.add(new int[] {101, 150});
- ranges.add(new int[] {21, 30});
+ ranges.add(new int[] { 101, 150 });
+ ranges.add(new int[] { 21, 30 });
overlaps = MapList.getMappedOffsetsForPositions(24, 40, ranges, 3, 1);
assertEquals(3, overlaps.cardinality());
assertTrue(overlaps.get(17));
assertTrue(overlaps.get(18));
assertTrue(overlaps.get(19));
-
+
/*
* reverse range 1:1 (e.g. reverse strand gene to transcript)
*/
ranges.clear();
- ranges.add(new int[] {20, 10});
+ ranges.add(new int[] { 20, 10 });
overlaps = MapList.getMappedOffsetsForPositions(12, 13, ranges, 1, 1);
assertEquals(2, overlaps.cardinality());
assertTrue(overlaps.get(7));
assertTrue(overlaps.get(8));
-
+
/*
* reverse range 3:1 (e.g. reverse strand gene to peptide)
* from EMBL:J03321 to P0CE20
*/
ranges.clear();
- ranges.add(new int[] {1480, 488});
- overlaps = MapList.getMappedOffsetsForPositions(1460, 1460, ranges, 3, 1);
+ ranges.add(new int[] { 1480, 488 });
+ overlaps = MapList.getMappedOffsetsForPositions(1460, 1460, ranges, 3,
+ 1);
// 1460 is the end of the 7th codon
assertEquals(1, overlaps.cardinality());
assertTrue(overlaps.get(6));
// add one base (part codon)
- overlaps = MapList.getMappedOffsetsForPositions(1459, 1460, ranges, 3, 1);
+ overlaps = MapList.getMappedOffsetsForPositions(1459, 1460, ranges, 3,
+ 1);
assertEquals(2, overlaps.cardinality());
assertTrue(overlaps.get(6));
assertTrue(overlaps.get(7));
// add second base (part codon)
- overlaps = MapList.getMappedOffsetsForPositions(1458, 1460, ranges, 3, 1);
+ overlaps = MapList.getMappedOffsetsForPositions(1458, 1460, ranges, 3,
+ 1);
assertEquals(2, overlaps.cardinality());
assertTrue(overlaps.get(6));
assertTrue(overlaps.get(7));
// add third base (whole codon)
- overlaps = MapList.getMappedOffsetsForPositions(1457, 1460, ranges, 3, 1);
+ overlaps = MapList.getMappedOffsetsForPositions(1457, 1460, ranges, 3,
+ 1);
assertEquals(2, overlaps.cardinality());
assertTrue(overlaps.get(6));
assertTrue(overlaps.get(7));
// add one more base (part codon)
- overlaps = MapList.getMappedOffsetsForPositions(1456, 1460, ranges, 3, 1);
+ overlaps = MapList.getMappedOffsetsForPositions(1456, 1460, ranges, 3,
+ 1);
assertEquals(3, overlaps.cardinality());
assertTrue(overlaps.get(6));
assertTrue(overlaps.get(7));
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNull;
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
-import static org.testng.AssertJUnit.fail;
+import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
import java.awt.Color;
import java.io.IOException;
}
@Test(groups = "Functional")
- public void testListToArray()
+ public void testFindOverlap()
{
List<int[]> ranges = new ArrayList<>();
-
- int[] result = MappingUtils.rangeListToArray(ranges);
- assertEquals(result.length, 0);
- ranges.add(new int[] { 24, 12 });
- result = MappingUtils.rangeListToArray(ranges);
- assertEquals(result.length, 2);
- assertEquals(result[0], 24);
- assertEquals(result[1], 12);
- ranges.add(new int[] { -7, 30 });
- result = MappingUtils.rangeListToArray(ranges);
- assertEquals(result.length, 4);
- assertEquals(result[0], 24);
- assertEquals(result[1], 12);
- assertEquals(result[2], -7);
- assertEquals(result[3], 30);
- try
- {
- MappingUtils.rangeListToArray(null);
- fail("Expected exception");
- } catch (NullPointerException e)
- {
- // expected
- }
+ ranges.add(new int[] { 4, 8 });
+ ranges.add(new int[] { 10, 12 });
+ ranges.add(new int[] { 16, 19 });
+
+ int[] overlap = MappingUtils.findOverlap(ranges, 5, 13);
+ assertArrayEquals(overlap, new int[] { 5, 12 });
+ overlap = MappingUtils.findOverlap(ranges, -100, 100);
+ assertArrayEquals(overlap, new int[] { 4, 19 });
+ overlap = MappingUtils.findOverlap(ranges, 7, 17);
+ assertArrayEquals(overlap, new int[] { 7, 17 });
+ overlap = MappingUtils.findOverlap(ranges, 13, 15);
+ assertNull(overlap);
}
/**
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
import jalview.datamodel.AlignmentI;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.DBRefSource;
import jalview.xml.binding.embl.EntryType.Feature.Qualifier;
import jalview.xml.binding.embl.XrefType;
-import java.io.ByteArrayInputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
public class EmblXmlSourceTest
{
// exact length match:
assertSame(exons, EmblXmlSource.adjustForProteinLength(6, exons));
- // match if we assume exons include stop codon not in protein:
- assertSame(exons, EmblXmlSource.adjustForProteinLength(5, exons));
+ // truncate last exon by 3bp (e.g. stop codon)
+ int[] truncated = EmblXmlSource.adjustForProteinLength(5, exons);
+ assertEquals("[11, 15, 21, 25, 31, 35]", Arrays.toString(truncated));
// truncate last exon by 6bp
- int[] truncated = EmblXmlSource.adjustForProteinLength(4, exons);
+ truncated = EmblXmlSource.adjustForProteinLength(4, exons);
assertEquals("[11, 15, 21, 25, 31, 32]", Arrays.toString(truncated));
// remove last exon and truncate preceding by 1bp