X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FAlignedCodonFrame.java;h=d24593ad444df3d86bdaa86c72946223b37c8e3c;hb=e1435414d9938464ecb0f3e4d7920d4983e757f7;hp=627f0a6a6ba112e3178ed909e80432ca8a551b10;hpb=4d7f98a6dd54d9863ba449ec79dcd95d25ed863d;p=jalview.git diff --git a/src/jalview/datamodel/AlignedCodonFrame.java b/src/jalview/datamodel/AlignedCodonFrame.java index 627f0a6..d24593a 100644 --- a/src/jalview/datamodel/AlignedCodonFrame.java +++ b/src/jalview/datamodel/AlignedCodonFrame.java @@ -399,13 +399,13 @@ public class AlignedCodonFrame return null; } MapList ml = null; - char[] dnaSeq = null; + SequenceI dnaSeq = null; for (int i = 0; i < dnaToProt.length; i++) { if (dnaToProt[i].to == protein) { ml = getdnaToProt()[i]; - dnaSeq = dnaSeqs[i].getSequence(); + dnaSeq = dnaSeqs[i]; break; } } @@ -423,8 +423,10 @@ public class AlignedCodonFrame * Read off the mapped nucleotides (converting to position base 0) */ codonPos = MappingUtils.flattenRanges(codonPos); - return new char[] { dnaSeq[codonPos[0] - 1], dnaSeq[codonPos[1] - 1], - dnaSeq[codonPos[2] - 1] }; + char[] dna = dnaSeq.getSequence(); + int start = dnaSeq.getStart(); + return new char[] { dna[codonPos[0] - start], dna[codonPos[1] - start], + dna[codonPos[2] - start] }; } /** @@ -459,4 +461,117 @@ public class AlignedCodonFrame } return result; } + + /** + * Test whether the given sequence is substitutable for one or more dummy + * sequences in this mapping + * + * @param map + * @param seq + * @return + */ + public boolean isRealisableWith(SequenceI seq) + { + return realiseWith(seq, false) > 0; + } + + /** + * Replace any matchable mapped dummy sequences with the given real one. + * Returns the count of sequence mappings instantiated. + * + * @param seq + * @return + */ + public int realiseWith(SequenceI seq) + { + return realiseWith(seq, true); + } + + /** + * Returns the number of mapped dummy sequences that could be replaced with + * the given real sequence. + * + * @param seq + * a dataset sequence + * @param doUpdate + * if true, performs replacements, else only counts + * @return + */ + protected int realiseWith(SequenceI seq, boolean doUpdate) + { + SequenceI ds = seq.getDatasetSequence() != null ? seq + .getDatasetSequence() : seq; + int count = 0; + + /* + * check for replaceable DNA ('map from') sequences + */ + for (int i = 0; i < dnaSeqs.length; i++) + { + SequenceI dna = dnaSeqs[i]; + if (dna instanceof SequenceDummy + && dna.getName().equals(ds.getName())) + { + Mapping mapping = dnaToProt[i]; + int mapStart = mapping.getMap().getFromLowest(); + int mapEnd = mapping.getMap().getFromHighest(); + boolean mappable = couldReplaceSequence(dna, ds, mapStart, mapEnd); + if (mappable) + { + count++; + if (doUpdate) + { + dnaSeqs[i] = ds; + } + } + } + + /* + * check for replaceable protein ('map to') sequences + */ + SequenceI prot = dnaToProt[i].getTo(); + Mapping mapping = dnaToProt[i]; + int mapStart = mapping.getMap().getToLowest(); + int mapEnd = mapping.getMap().getToHighest(); + boolean mappable = couldReplaceSequence(prot, ds, mapStart, mapEnd); + if (mappable) + { + count++; + if (doUpdate) + { + dnaToProt[i].setTo(ds); + } + } + } + return count; + } + + /** + * Helper method to test whether a 'real' sequence could replace a 'dummy' + * sequence in the map. The criteria are that they have the same name, and + * that the mapped region overlaps the candidate sequence. + * + * @param existing + * @param replacement + * @param mapStart + * @param mapEnd + * @return + */ + protected static boolean couldReplaceSequence(SequenceI existing, + SequenceI replacement, int mapStart, int mapEnd) + { + if (existing instanceof SequenceDummy + && existing.getName().equals(replacement.getName())) + { + int start = replacement.getStart(); + int end = replacement.getEnd(); + boolean mappingOverlapsSequence = (mapStart >= start && mapStart <= end) + || (mapEnd >= start && mapEnd <= end); + if (mappingOverlapsSequence) + { + return true; + } + } + return false; + } }