From: Jim Procter Date: Fri, 4 Feb 2022 14:34:20 +0000 (+0000) Subject: Merge branch 'bug/JAL-3806_mappingCoversSequence_for2112' into develop X-Git-Tag: Release_2_11_2_0~13^2~4 X-Git-Url: http://source.jalview.org/gitweb/?p=jalview.git;a=commitdiff_plain;h=4d71acba1cc4999e8e4061ec3e9ae55e1b37084e Merge branch 'bug/JAL-3806_mappingCoversSequence_for2112' into develop Combines patches for JAL-3806 prior to redaction of shared CDS dataset sequences with patches for JAL-3673 Conflicts: src/jalview/datamodel/AlignedCodonFrame.java src/jalview/util/MappingUtils.java test/jalview/util/MappingUtilsTest.java --- 4d71acba1cc4999e8e4061ec3e9ae55e1b37084e diff --cc src/jalview/datamodel/AlignedCodonFrame.java index 2f33e43,eda1a13..b376c80 --- a/src/jalview/datamodel/AlignedCodonFrame.java +++ b/src/jalview/datamodel/AlignedCodonFrame.java @@@ -160,7 -210,7 +210,7 @@@ public class AlignedCodonFram /** * Adds any regions mapped to or from position {@code pos} in sequence * {@code seq} to the given search results -- * ++ * Note: recommend first using the .covers(,true,true) to ensure mapping covers both sequences * @param seq * @param pos * @param sr @@@ -395,15 -441,71 +445,17 @@@ public void markMappedRegion(SequenceI seq, int index, SearchResultsI results) { - int[] codon; SequenceI ds = seq.getDatasetSequence(); - for (SequenceToSequenceMapping ssm : mappings) + if (ds == null) { - if (ssm.covers(seq,true,true)) - { - if ((ssm.fromSeq == seq || ssm.fromSeq == ds)) - { - codon = ssm.mapping.map.locateInTo(index, index); - if (codon != null) - { - for (int i = 0; i < codon.length; i += 2) - { - results.addResult(ssm.mapping.to, codon[i], codon[i + 1]); - } - } - } - else if ((ssm.mapping.to == seq || ssm.mapping.to == ds)) - { - { - codon = ssm.mapping.map.locateInFrom(index, index); - if (codon != null) - { - for (int i = 0; i < codon.length; i += 2) - { - results.addResult(ssm.fromSeq, codon[i], codon[i + 1]); - } - } - } - }} + ds = seq; } - } - - /** - * Returns the DNA codon positions (base 1) for the given position (base 1) in - * a mapped protein sequence, or null if no mapping is found. - * - * Intended for use in aligning cDNA to match aligned protein. Only the first - * mapping found is returned, so not suitable for use if multiple protein - * sequences are mapped to the same cDNA (but aligning cDNA as protein is - * ill-defined for this case anyway). - * - * @param seq - * the DNA dataset sequence - * @param aaPos - * residue position (base 1) in a protein sequence - * @return - */ - public int[] getDnaPosition(SequenceI seq, int aaPos) - { - /* - * Adapted from markMappedRegion(). - */ - MapList ml = null; - int i = 0; for (SequenceToSequenceMapping ssm : mappings) { - ssm.markMappedRegion(ds, index, results); - if (ssm.fromSeq == seq) - { - ml = getdnaToProt()[i]; - break; ++ if (ssm.covers(seq,true,true)) { ++ ssm.markMappedRegion(ds, index, results); + } - i++; } - return ml == null ? null : ml.locateInFrom(aaPos, aaPos); } /** diff --cc src/jalview/util/MappingUtils.java index 590e1c5,c66fe00..86b7a6d --- a/src/jalview/util/MappingUtils.java +++ b/src/jalview/util/MappingUtils.java @@@ -363,49 -364,53 +364,55 @@@ public final class MappingUtil */ int startResiduePos = selected.findPosition(firstUngappedPos); int endResiduePos = selected.findPosition(lastUngappedPos); - - for (AlignedCodonFrame acf : codonFrames) + for (SequenceI seq : mapTo.getAlignment().getSequences()) { - for (SequenceI seq : mapTo.getAlignment().getSequences()) + int mappedStartResidue = 0; + int mappedEndResidue = 0; + for (AlignedCodonFrame acf : codonFrames) { - SequenceI peptide = targetIsNucleotide ? selected : seq; - SequenceI cds = targetIsNucleotide ? seq : selected; - SequenceToSequenceMapping s2s = acf.getCoveringMapping(cds, - peptide); - if (s2s == null) - { - continue; - } - int mappedStartResidue = 0; - int mappedEndResidue = 0; - List mapping = Arrays.asList(acf); - SearchResultsI sr = buildSearchResults(selected, startResiduePos, - mapping); - for (SearchResultMatchI m : sr.getResults()) ++ // rather than use acf.getCoveringMapping() we iterate through all ++ // mappings to make sure all CDS are selected for a protein + for (SequenceToSequenceMapping map: acf.getMappings()) { - mappedStartResidue = m.getStart(); - mappedEndResidue = m.getEnd(); - } - sr = buildSearchResults(selected, endResiduePos, mapping); - for (SearchResultMatchI m : sr.getResults()) + if (map.covers(selected) && map.covers(seq)) { - mappedStartResidue = Math.min(mappedStartResidue, m.getStart()); - mappedEndResidue = Math.max(mappedEndResidue, m.getEnd()); - } + /* + * Found a sequence mapping. Locate the start/end mapped residues. + */ + List mapping = Arrays + .asList(new AlignedCodonFrame[] + { acf }); + // locate start + SearchResultsI sr = buildSearchResults(selected, + startResiduePos, mapping); + for (SearchResultMatchI m : sr.getResults()) + { + mappedStartResidue = m.getStart(); + mappedEndResidue = m.getEnd(); + } + // locate end - allowing for adjustment of start range + sr = buildSearchResults(selected, endResiduePos, mapping); + for (SearchResultMatchI m : sr.getResults()) + { + mappedStartResidue = Math.min(mappedStartResidue, + m.getStart()); + mappedEndResidue = Math.max(mappedEndResidue, m.getEnd()); + } - /* - * Find the mapped aligned columns, save the range. Note findIndex - * returns a base 1 position, SequenceGroup uses base 0 - */ - int mappedStartCol = seq.findIndex(mappedStartResidue) - 1; - minStartCol = minStartCol == -1 ? mappedStartCol - : Math.min(minStartCol, mappedStartCol); - int mappedEndCol = seq.findIndex(mappedEndResidue) - 1; - maxEndCol = maxEndCol == -1 ? mappedEndCol - : Math.max(maxEndCol, mappedEndCol); - mappedGroup.addSequence(seq, false); - break; - } + /* + * Find the mapped aligned columns, save the range. Note findIndex + * returns a base 1 position, SequenceGroup uses base 0 + */ + int mappedStartCol = seq.findIndex(mappedStartResidue) - 1; + minStartCol = minStartCol == -1 ? mappedStartCol + : Math.min(minStartCol, mappedStartCol); + int mappedEndCol = seq.findIndex(mappedEndResidue) - 1; + maxEndCol = maxEndCol == -1 ? mappedEndCol + : Math.max(maxEndCol, mappedEndCol); + mappedGroup.addSequence(seq, false); + break; + } + }} } } mappedGroup.setStartRes(minStartCol < 0 ? 0 : minStartCol);