X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fviewmodel%2Fseqfeatures%2FFeatureRendererModel.java;h=821f7f47d0661d31a34604026ce285a16a965791;hb=3740241b6d0dfa109dc81847afe58f17497c39e8;hp=1f697760dbe93ff35758ad1254997bc010b7c85e;hpb=de32fd704f78dafa5bed5eb64f9f96fab320971f;p=jalview.git diff --git a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java index 1f69776..821f7f4 100644 --- a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java +++ b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java @@ -23,7 +23,12 @@ package jalview.viewmodel.seqfeatures; import jalview.api.AlignViewportI; import jalview.api.FeatureColourI; import jalview.api.FeaturesDisplayedI; +import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.AlignmentI; +import jalview.datamodel.Mapping; +import jalview.datamodel.SearchResultMatchI; +import jalview.datamodel.SearchResults; +import jalview.datamodel.SearchResultsI; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.datamodel.features.FeatureMatcherSetI; @@ -983,7 +988,7 @@ public abstract class FeatureRendererModel * @param sequenceFeature * @return */ - protected boolean featureGroupNotShown(final SequenceFeature sequenceFeature) + public boolean featureGroupNotShown(final SequenceFeature sequenceFeature) { return featureGroups != null && sequenceFeature.featureGroup != null @@ -998,7 +1003,7 @@ public abstract class FeatureRendererModel */ @Override public List findFeaturesAtResidue(SequenceI sequence, - int resNo) + int fromResNo, int toResNo) { List result = new ArrayList<>(); if (!av.areFeaturesDisplayed() || getFeaturesDisplayed() == null) @@ -1016,7 +1021,7 @@ public abstract class FeatureRendererModel String[] visibleTypes = visibleFeatures .toArray(new String[visibleFeatures.size()]); List features = sequence.getFeatures().findFeatures( - resNo, resNo, visibleTypes); + fromResNo, toResNo, visibleTypes); for (SequenceFeature sf : features) { @@ -1150,4 +1155,53 @@ public abstract class FeatureRendererModel return filter == null ? true : filter.matches(sf); } + /** + * Answers a (possibly empty) list of features in this alignment at a position + * (or range) which is mappable from the given sequence residue position in a + * mapped alignment. + * + * @param sequence + * @param pos + * @return + */ + public List findComplementFeaturesAtResidue(SequenceI sequence, int pos) + { + SequenceI ds = sequence.getDatasetSequence(); + List result = new ArrayList<>(); + List mappings = this.av.getAlignment() + .getCodonFrame(sequence); + + /* + * todo: direct lookup of CDS for peptide and vice-versa; for now, + * have to search through an unordered list of mappings for a candidate + */ + for (AlignedCodonFrame acf : mappings) + { + Mapping mapping = acf.getMappingForSequence(sequence, true); + if (mapping == null || mapping.getMap().getFromRatio() == mapping + .getMap().getToRatio()) + { + continue; // we are only looking for 3:1 or 1:3 mappings + } + SearchResultsI sr = new SearchResults(); + acf.markMappedRegion(ds, pos, sr); + for (SearchResultMatchI match : sr.getResults()) + { + int fromRes = match.getStart(); + int toRes = match.getEnd(); + List fs = findFeaturesAtResidue( + match.getSequence(), fromRes, toRes); + for (SequenceFeature sf : fs) + { + if (!result.contains(sf)) + { + result.add(sf); + } + } + } + } + + return result; + } + }