X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FAlignedCodonFrame.java;h=7845ddcf6925d5035c615e2f56dff45c8a5ae484;hb=947109cebef3e98693ffc0a70b5bffcbd32217e2;hp=5dfd434e81bd29af02855a6f9e833f633959a1ee;hpb=36394666b7848eb7c2569188dad062c7d450d612;p=jalview.git diff --git a/src/jalview/datamodel/AlignedCodonFrame.java b/src/jalview/datamodel/AlignedCodonFrame.java index 5dfd434..7845ddc 100644 --- a/src/jalview/datamodel/AlignedCodonFrame.java +++ b/src/jalview/datamodel/AlignedCodonFrame.java @@ -23,6 +23,7 @@ package jalview.datamodel; import jalview.util.MapList; import jalview.util.MappingUtils; +import java.util.AbstractList; import java.util.ArrayList; import java.util.List; @@ -33,40 +34,14 @@ import java.util.List; public class AlignedCodonFrame { - /* - * Data bean to hold mappings from one sequence to another - */ - private class SequenceToSequenceMapping - { - private SequenceI fromSeq; - - private Mapping mapping; - - SequenceToSequenceMapping(SequenceI from, Mapping map) - { - this.fromSeq = from; - this.mapping = map; - } - - /** - * Readable representation for debugging only, not guaranteed not to change - */ - @Override - public String toString() - { - return String.format("From %s %s", fromSeq.getName(), - mapping.toString()); - } - } - - private List mappings; + private List mappings; /** * Constructor */ public AlignedCodonFrame() { - mappings = new ArrayList(); + mappings = new ArrayList<>(); } /** @@ -79,19 +54,36 @@ public class AlignedCodonFrame */ public void addMap(SequenceI dnaseq, SequenceI aaseq, MapList map) { + addMap(dnaseq, aaseq, map, null); + } + + /** + * Adds a mapping between the dataset sequences for the associated dna and + * protein sequence objects + * + * @param dnaseq + * @param aaseq + * @param map + * @param mapFromId + */ + public void addMap(SequenceI dnaseq, SequenceI aaseq, MapList map, + String mapFromId) + { // JBPNote DEBUG! THIS ! // dnaseq.transferAnnotation(aaseq, mp); // aaseq.transferAnnotation(dnaseq, new Mapping(map.getInverse())); SequenceI fromSeq = (dnaseq.getDatasetSequence() == null) ? dnaseq : dnaseq.getDatasetSequence(); - SequenceI toSeq = (aaseq.getDatasetSequence() == null) ? aaseq : aaseq - .getDatasetSequence(); + SequenceI toSeq = (aaseq.getDatasetSequence() == null) ? aaseq + : aaseq.getDatasetSequence(); /* * if we already hold a mapping between these sequences, just add to it + * note that 'adding' a duplicate map does nothing; this protects against + * creating duplicate mappings in AlignedCodonFrame */ - for (SequenceToSequenceMapping ssm : mappings) + for (SequenceMapping ssm : mappings) { if (ssm.fromSeq == fromSeq && ssm.mapping.to == toSeq) { @@ -104,15 +96,16 @@ public class AlignedCodonFrame * otherwise, add a new sequence mapping */ Mapping mp = new Mapping(toSeq, map); - mappings.add(new SequenceToSequenceMapping(fromSeq, mp)); + mp.setMappedFromId(mapFromId); + mappings.add(new SequenceMapping(fromSeq, mp)); } public SequenceI[] getdnaSeqs() { // TODO return a list instead? // return dnaSeqs; - List seqs = new ArrayList(); - for (SequenceToSequenceMapping ssm : mappings) + List seqs = new ArrayList<>(); + for (SequenceMapping ssm : mappings) { seqs.add(ssm.fromSeq); } @@ -122,8 +115,8 @@ public class AlignedCodonFrame public SequenceI[] getAaSeqs() { // TODO not used - remove? - List seqs = new ArrayList(); - for (SequenceToSequenceMapping ssm : mappings) + List seqs = new ArrayList<>(); + for (SequenceMapping ssm : mappings) { seqs.add(ssm.mapping.to); } @@ -132,8 +125,8 @@ public class AlignedCodonFrame public MapList[] getdnaToProt() { - List maps = new ArrayList(); - for (SequenceToSequenceMapping ssm : mappings) + List maps = new ArrayList<>(); + for (SequenceMapping ssm : mappings) { maps.add(ssm.mapping.map); } @@ -142,8 +135,8 @@ public class AlignedCodonFrame public Mapping[] getProtMappings() { - List maps = new ArrayList(); - for (SequenceToSequenceMapping ssm : mappings) + List maps = new ArrayList<>(); + for (SequenceMapping ssm : mappings) { maps.add(ssm.mapping); } @@ -157,16 +150,20 @@ public class AlignedCodonFrame * @param seq * @return */ - public Mapping getMappingForSequence(SequenceI seq) + public Mapping getMappingForSequence(SequenceI seq, boolean cdsOnly) { SequenceI seqDs = seq.getDatasetSequence(); seqDs = seqDs != null ? seqDs : seq; - for (SequenceToSequenceMapping ssm : mappings) + for (SequenceMapping ssm : mappings) { if (ssm.fromSeq == seqDs || ssm.mapping.to == seqDs) { - return ssm.mapping; + if (!cdsOnly || ssm.fromSeq.getName().startsWith("CDS") + || ssm.mapping.to.getName().startsWith("CDS")) + { + return ssm.mapping; + } } } return null; @@ -182,7 +179,7 @@ public class AlignedCodonFrame public SequenceI getAaForDnaSeq(SequenceI dnaSeqRef) { SequenceI dnads = dnaSeqRef.getDatasetSequence(); - for (SequenceToSequenceMapping ssm : mappings) + for (SequenceMapping ssm : mappings) { if (ssm.fromSeq == dnaSeqRef || ssm.fromSeq == dnads) { @@ -200,7 +197,7 @@ public class AlignedCodonFrame public SequenceI getDnaForAaSeq(SequenceI aaSeqRef) { SequenceI aads = aaSeqRef.getDatasetSequence(); - for (SequenceToSequenceMapping ssm : mappings) + for (SequenceMapping ssm : mappings) { if (ssm.mapping.to == aaSeqRef || ssm.mapping.to == aads) { @@ -234,11 +231,11 @@ public class AlignedCodonFrame * where highlighted regions go */ public void markMappedRegion(SequenceI seq, int index, - SearchResults results) + SearchResultsI results) { int[] codon; SequenceI ds = seq.getDatasetSequence(); - for (SequenceToSequenceMapping ssm : mappings) + for (SequenceMapping ssm : mappings) { if (ssm.fromSeq == seq || ssm.fromSeq == ds) { @@ -289,7 +286,7 @@ public class AlignedCodonFrame */ MapList ml = null; int i = 0; - for (SequenceToSequenceMapping ssm : mappings) + for (SequenceMapping ssm : mappings) { if (ssm.fromSeq == seq) { @@ -303,7 +300,8 @@ public class AlignedCodonFrame /** * Convenience method to return the first aligned sequence in the given - * alignment whose dataset has a mapping with the given dataset sequence. + * alignment whose dataset has a mapping with the given (aligned or dataset) + * sequence. * * @param seq * @@ -315,13 +313,14 @@ public class AlignedCodonFrame /* * Search mapped protein ('to') sequences first. */ - for (SequenceToSequenceMapping ssm : mappings) + for (SequenceMapping ssm : mappings) { - if (ssm.fromSeq == seq) + if (ssm.fromSeq == seq || ssm.fromSeq == seq.getDatasetSequence()) { for (SequenceI sourceAligned : al.getSequences()) { - if (ssm.mapping.to == sourceAligned.getDatasetSequence()) + if (ssm.mapping.to == sourceAligned.getDatasetSequence() + || ssm.mapping.to == sourceAligned) { return sourceAligned; } @@ -332,9 +331,10 @@ public class AlignedCodonFrame /* * Then try mapped dna sequences. */ - for (SequenceToSequenceMapping ssm : mappings) + for (SequenceMapping ssm : mappings) { - if (ssm.mapping.to == seq) + if (ssm.mapping.to == seq + || ssm.mapping.to == seq.getDatasetSequence()) { for (SequenceI sourceAligned : al.getSequences()) { @@ -364,13 +364,13 @@ public class AlignedCodonFrame { SequenceI targetDs = target.getDatasetSequence() == null ? target : target.getDatasetSequence(); - SequenceI queryDs = query.getDatasetSequence() == null ? query : query - .getDatasetSequence(); + SequenceI queryDs = query.getDatasetSequence() == null ? query + : query.getDatasetSequence(); if (targetDs == null || queryDs == null /*|| dnaToProt == null*/) { return null; } - for (SequenceToSequenceMapping ssm : mappings) + for (SequenceMapping ssm : mappings) { /* * try mapping from target to query @@ -414,11 +414,12 @@ public class AlignedCodonFrame { MapList ml = null; SequenceI dnaSeq = null; - List result = new ArrayList(); + List result = new ArrayList<>(); - for (SequenceToSequenceMapping ssm : mappings) + for (SequenceMapping ssm : mappings) { - if (ssm.mapping.to == protein) + if (ssm.mapping.to == protein + && ssm.mapping.getMap().getFromRatio() == 3) { ml = ssm.mapping.map; dnaSeq = ssm.fromSeq; @@ -433,33 +434,34 @@ public class AlignedCodonFrame * Read off the mapped nucleotides (converting to position base 0) */ codonPos = MappingUtils.flattenRanges(codonPos); - char[] dna = dnaSeq.getSequence(); int start = dnaSeq.getStart(); - result.add(new char[] { dna[codonPos[0] - start], - dna[codonPos[1] - start], dna[codonPos[2] - start] }); + char c1 = dnaSeq.getCharAt(codonPos[0] - start); + char c2 = dnaSeq.getCharAt(codonPos[1] - start); + char c3 = dnaSeq.getCharAt(codonPos[2] - start); + result.add(new char[] { c1, c2, c3 }); } } return result.isEmpty() ? null : result; } /** - * Returns any mappings found which are to (or from) the given sequence, and - * to distinct sequences. + * Returns any mappings found which are from the given sequence, and to + * distinct sequences. * * @param seq * @return */ - public List getMappingsForSequence(SequenceI seq) + public List getMappingsFromSequence(SequenceI seq) { - List result = new ArrayList(); - List related = new ArrayList(); + List result = new ArrayList<>(); + List related = new ArrayList<>(); SequenceI seqDs = seq.getDatasetSequence(); seqDs = seqDs != null ? seqDs : seq; - for (SequenceToSequenceMapping ssm : mappings) + for (SequenceMapping ssm : mappings) { final Mapping mapping = ssm.mapping; - if (ssm.fromSeq == seqDs || mapping.to == seqDs) + if (ssm.fromSeq == seqDs) { if (!related.contains(mapping.to)) { @@ -508,14 +510,15 @@ public class AlignedCodonFrame */ protected int realiseWith(SequenceI seq, boolean doUpdate) { - SequenceI ds = seq.getDatasetSequence() != null ? seq - .getDatasetSequence() : seq; + SequenceI ds = seq.getDatasetSequence() != null + ? seq.getDatasetSequence() + : seq; int count = 0; /* * check for replaceable DNA ('map from') sequences */ - for (SequenceToSequenceMapping ssm : mappings) + for (SequenceMapping ssm : mappings) { SequenceI dna = ssm.fromSeq; if (dna instanceof SequenceDummy @@ -583,8 +586,8 @@ public class AlignedCodonFrame { int start = replacement.getStart(); int end = replacement.getEnd(); - boolean mappingOverlapsSequence = (mapStart >= start && mapStart <= end) - || (mapEnd >= start && mapEnd <= end); + boolean mappingOverlapsSequence = (mapStart >= start + && mapStart <= end) || (mapEnd >= start && mapEnd <= end); if (mappingOverlapsSequence) { return true; @@ -608,7 +611,7 @@ public class AlignedCodonFrame } SequenceI ds = seq.getDatasetSequence(); - for (SequenceToSequenceMapping ssm : mappings) + for (SequenceMapping ssm : mappings) /* * 'from' sequences */ @@ -637,4 +640,76 @@ public class AlignedCodonFrame { return mappings.isEmpty(); } + + /** + * Method for debug / inspection purposes only, may change in future + */ + @Override + public String toString() + { + return mappings == null ? "null" : mappings.toString(); + } + + /** + * Returns the first mapping found that is between 'fromSeq' and 'toSeq', or + * null if none found + * + * @param fromSeq + * aligned or dataset sequence + * @param toSeq + * aligned or dataset sequence + * @return + */ + public Mapping getMappingBetween(SequenceI fromSeq, SequenceI toSeq) + { + SequenceI dssFrom = fromSeq.getDatasetSequence() == null ? fromSeq + : fromSeq.getDatasetSequence(); + SequenceI dssTo = toSeq.getDatasetSequence() == null ? toSeq + : toSeq.getDatasetSequence(); + + for (SequenceMapping mapping : mappings) + { + SequenceI from = mapping.fromSeq; + SequenceI to = mapping.mapping.to; + if ((from == dssFrom && to == dssTo) + || (from == dssTo && to == dssFrom)) + { + return mapping.mapping; + } + } + return null; + } + + /** + * Returns a hashcode derived from the list of sequence mappings + * + * @see SequenceMapping#hashCode() + * @see AbstractList#hashCode() + */ + @Override + public int hashCode() + { + return this.mappings.hashCode(); + } + + /** + * Two AlignedCodonFrame objects are equal if they hold the same ordered list + * of mappings + * + * @see SequenceToSequenceMapping# + */ + @Override + public boolean equals(Object obj) + { + if (!(obj instanceof AlignedCodonFrame)) + { + return false; + } + return this.mappings.equals(((AlignedCodonFrame) obj).mappings); + } + + public List getMappings() + { + return mappings; + } }