+ * The main use case for this method is when mapping cDNA sequence to its + * protein product, based on CDS feature ranges which derive from spliced + * exons, but are contiguous on the cDNA sequence. For example + *
+ * CDS 1-20 // from exon1 + * CDS 21-35 // from exon2 + * CDS 36-71 // from exon3 + * 'coalesce' to range 1-71 + *+ * + * @param ranges + * @return the same list (if unchanged), else a new merged list, leaving the + * input list unchanged + */ + public static List
+ * Returns null if the mappings cannot be traversed (not all toRanges of this + * map correspond to fromRanges of the input), or if this.toRatio does not + * match map.fromRatio. + * + *
+ * Example 1: + * this: from [1-100] to [501-600] + * input: from [10-40] to [60-90] + * output: from [10-40] to [560-590] + * Example 2 ('reverse strand exons'): + * this: from [1-100] to [2000-1951], [1000-951] // transcript to loci + * input: from [1-50] to [41-90] // CDS to transcript + * output: from [10-40] to [1960-1951], [1000-971] // CDS to gene loci + *+ * + * @param map + * @return + */ + public MapList traverse(MapList map) { - MapList ml = new MapList(new int[] - {1, 5, 10, 15, 25, 20}, - new int[] - {51, 1}, 1, 3); - MapList ml1 = new MapList(new int[] - {1, 3, 17, 4}, - new int[] - {51, 1}, 1, 3); + if (map == null) + { + return null; + } - // test internal consistency - int to[] = new int[51]; - MapList.testMap(ml, 1, 25); /* - for (int from=1; from<=51; from++) { - int[] too=ml.shiftTo(from); - int[] toofrom=ml.shiftFrom(too[0]); - System.out.println("ShiftFrom("+from+")=="+too[0]+" % "+too[1]+"\t+-+\tShiftTo("+too[0]+")=="+toofrom[0]+" % "+toofrom[1]); - }*/ - System.out.print("Success?\n"); // if we get here - something must be working! + * compound the ratios by this rule: + * A:B with M:N gives A*M:B*N + * reduced by greatest common divisor + * so 1:3 with 3:3 is 3:9 or 1:3 + * 1:3 with 3:1 is 3:3 or 1:1 + * 1:3 with 1:3 is 1:9 + * 2:5 with 3:7 is 6:35 + */ + int outFromRatio = getFromRatio() * map.getFromRatio(); + int outToRatio = getToRatio() * map.getToRatio(); + int gcd = MathUtils.gcd(outFromRatio, outToRatio); + outFromRatio /= gcd; + outToRatio /= gcd; + + List