From: gmungoc Date: Fri, 17 Apr 2020 13:00:10 +0000 (+0100) Subject: JAL-3567 unit tests for linked feature tooltips X-Git-Tag: Develop-2_11_2_0-d20201215~33^2~2 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=69e8792b5f1ed2c02cff0a1ee328793ab5c0f423;hp=de96de2488774840f2f6298d757369f9e43acaee;p=jalview.git JAL-3567 unit tests for linked feature tooltips --- diff --git a/src/jalview/datamodel/MappedFeatures.java b/src/jalview/datamodel/MappedFeatures.java index 520ff92..87609c6 100644 --- a/src/jalview/datamodel/MappedFeatures.java +++ b/src/jalview/datamodel/MappedFeatures.java @@ -29,21 +29,16 @@ public class MappedFeatures /* * the sequence the mapped features are on */ - private final SequenceI linkedSeq; + private final SequenceI featureSequence; /* * the mapping between sequences; - * NB this could be in either sense + * NB this could be in either sense (from or to featureSequence) */ private final Mapping mapping; /* - * if true, mapping is from the linked sequence, else to the linked sequence - */ - private boolean mappingIsFromLinkedSequence; - - /* - * features on linkedSeq that overlap the mapped positions + * features on featureSequence that overlap the mapped positions */ public final List features; @@ -70,22 +65,23 @@ public class MappedFeatures * Constructor * * @param theMapping - * @param from - * the sequence mapped from (e.g. CDS) + * sequence mapping (which may be either to, or from, the sequence + * holding the linked features) + * @param featureSeq + * the sequence hosting the virtual features * @param pos - * the residue position in the sequence mapped to + * the residue position in the sequence mapped to * @param res - * the residue character at position pos + * the residue character at position pos * @param theFeatures - * list of mapped features found in the 'from' sequence at - * the mapped position(s) + * list of mapped features found in the 'featureSeq' sequence at the + * mapped position(s) */ - public MappedFeatures(Mapping theMapping, SequenceI from, int pos, + public MappedFeatures(Mapping theMapping, SequenceI featureSeq, int pos, char res, List theFeatures) { mapping = theMapping; - linkedSeq = from; - mappingIsFromLinkedSequence = mapping.to != linkedSeq; + featureSequence = featureSeq; toPosition = pos; toResidue = res; features = theFeatures; @@ -101,13 +97,13 @@ public class MappedFeatures { codonPos = codonPositions; baseCodon = new char[3]; - int cdsStart = linkedSeq.getStart(); + int cdsStart = featureSequence.getStart(); baseCodon[0] = Character - .toUpperCase(linkedSeq.getCharAt(codonPos[0] - cdsStart)); + .toUpperCase(featureSequence.getCharAt(codonPos[0] - cdsStart)); baseCodon[1] = Character - .toUpperCase(linkedSeq.getCharAt(codonPos[1] - cdsStart)); + .toUpperCase(featureSequence.getCharAt(codonPos[1] - cdsStart)); baseCodon[2] = Character - .toUpperCase(linkedSeq.getCharAt(codonPos[2] - cdsStart)); + .toUpperCase(featureSequence.getCharAt(codonPos[2] - cdsStart)); } else { @@ -255,7 +251,7 @@ public class MappedFeatures */ public String getLinkedSequenceName() { - return linkedSeq == null ? null : linkedSeq.getName(); + return featureSequence == null ? null : featureSequence.getName(); } /** @@ -278,16 +274,22 @@ public class MappedFeatures public int[] getMappedPositions(int begin, int end) { MapList map = mapping.getMap(); - return mappingIsFromLinkedSequence ? map.locateInTo(begin, end) - : map.locateInFrom(begin, end); + return mapping.to == featureSequence ? map.locateInFrom(begin, end) + : map.locateInTo(begin, end); } + /** + * Answers true if the linked features are on coding sequence, false if on + * peptide + * + * @return + */ public boolean isFromCds() { if (mapping.getMap().getFromRatio() == 3) { - return mappingIsFromLinkedSequence; + return mapping.to != featureSequence; } - return !mappingIsFromLinkedSequence; + return mapping.to == featureSequence; } } diff --git a/src/jalview/io/SequenceAnnotationReport.java b/src/jalview/io/SequenceAnnotationReport.java index 8328e7a..27c1652 100644 --- a/src/jalview/io/SequenceAnnotationReport.java +++ b/src/jalview/io/SequenceAnnotationReport.java @@ -216,6 +216,11 @@ public class SequenceAnnotationReport { beginRange = mf.getMappedPositions(begin, begin); endRange = mf.getMappedPositions(end, end); + if (beginRange == null || endRange == null) + { + // something went wrong + return false; + } begin = beginRange[0]; end = endRange[endRange.length - 1]; } diff --git a/test/jalview/datamodel/SequenceFeatureTest.java b/test/jalview/datamodel/SequenceFeatureTest.java index e105659..b4848a5 100644 --- a/test/jalview/datamodel/SequenceFeatureTest.java +++ b/test/jalview/datamodel/SequenceFeatureTest.java @@ -336,7 +336,7 @@ public class SequenceFeatureTest SequenceI seq = new Sequence("TestSeq/8-14", "PLRFQMD"); MapList map = new MapList(new int[] { 101, 118 }, new int[] { 8, 13 }, 3, 1); - Mapping mapping = new Mapping(seq.getDatasetSequence(), map); + Mapping mapping = new Mapping(seq, map); List features = new ArrayList<>(); // vary ttg (Leu) to ttc (Phe) SequenceFeature sf = new SequenceFeature("variant", "G,C", 106, 106, diff --git a/test/jalview/io/SequenceAnnotationReportTest.java b/test/jalview/io/SequenceAnnotationReportTest.java index 7e00caa..772ed2b 100644 --- a/test/jalview/io/SequenceAnnotationReportTest.java +++ b/test/jalview/io/SequenceAnnotationReportTest.java @@ -33,6 +33,8 @@ import org.testng.annotations.Test; import jalview.api.FeatureColourI; import jalview.datamodel.DBRefEntry; +import jalview.datamodel.MappedFeatures; +import jalview.datamodel.Mapping; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; @@ -40,6 +42,7 @@ import jalview.gui.JvOptionPane; import jalview.io.gff.GffConstants; import jalview.renderer.seqfeatures.FeatureRenderer; import jalview.schemes.FeatureColour; +import jalview.util.MapList; import jalview.viewmodel.seqfeatures.FeatureRendererModel; import junit.extensions.PA; @@ -423,4 +426,63 @@ public class SequenceAnnotationReportTest .endsWith( "
PDB7 3iu1
PDB8,...
(Output Sequence Details to list all database references)")); } + + /** + * Test adding a linked feature to the tooltip + */ + @Test(groups = "Functional") + public void testAppendFeature_virtualFeature() + { + /* + * map CDS to peptide sequence + */ + SequenceI cds = new Sequence("Cds/101-121", "CCTttgAGAtttCAAatgGAT"); + SequenceI peptide = new Sequence("Peptide/8-14", "PLRFQMD"); + MapList map = new MapList(new int[] { 101, 118 }, new int[] { 8, 13 }, + 3, 1); + Mapping mapping = new Mapping(peptide, map); + + /* + * assume variant feature found at CDS position 106 G>C + */ + List features = new ArrayList<>(); + // vary ttg (Leu) to ttc (Phe) + SequenceFeature sf = new SequenceFeature("variant", "G,C", 106, 106, + Float.NaN, null); + features.add(sf); + MappedFeatures mf = new MappedFeatures(mapping, cds, 9, 'L', features); + + StringBuilder sb = new StringBuilder(); + SequenceAnnotationReport sar = new SequenceAnnotationReport(false); + sar.appendFeature(sb, 1, null, sf, mf, 0); + + /* + * linked feature shown in tooltip in protein coordinates + */ + assertEquals("variant 9; G,C", sb.toString()); + + /* + * adding "alleles" attribute to variant allows peptide consequence + * to be calculated and added to the tooltip + */ + sf.setValue("alleles", "G,C"); + sb = new StringBuilder(); + sar.appendFeature(sb, 1, null, sf, mf, 0); + assertEquals("variant 9; G,C p.Leu9Phe", sb.toString()); + + /* + * now a virtual peptide feature on CDS + * feature at 11-12 on peptide maps to 110-115 on CDS + * here we test for tooltip at 113 (t) + */ + SequenceFeature sf2 = new SequenceFeature("metal", "Fe", 11, 12, + 2.3f, "Uniprot"); + features.clear(); + features.add(sf2); + mapping = new Mapping(peptide, map); + mf = new MappedFeatures(mapping, peptide, 113, 't', features); + sb = new StringBuilder(); + sar.appendFeature(sb, 1, null, sf2, mf, 0); + assertEquals("metal 110 115; Fe Score=2.3", sb.toString()); + } }