JAL-3763 Javadoc, check for null, additional tests task/JAL-3763_newDatasetForCds
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 22 Oct 2020 13:48:25 +0000 (14:48 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 22 Oct 2020 13:48:25 +0000 (14:48 +0100)
src/jalview/datamodel/AlignedCodonFrame.java
src/jalview/gui/PopupMenu.java
test/jalview/datamodel/AlignedCodonFrameTest.java

index a9875b4..2f33e43 100644 (file)
@@ -843,9 +843,9 @@ public class AlignedCodonFrame
   }
 
   /**
-   * Returns the first mapping found which is between the given sequence and
-   * another, is a triplet mapping (3:1 or 1:3), and covers the full extent of
-   * both sequences involved.
+   * Returns the first mapping found which is between the given dataset sequence
+   * and another, is a triplet mapping (3:1 or 1:3), and covers the full extent
+   * of both sequences involved
    * 
    * @param seq
    * @return
index 2a7fb9f..2f77959 100644 (file)
@@ -838,8 +838,13 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
        * show local rather than linked feature coordinates
        */
       int[] beginRange = mf.getMappedPositions(start, start);
-      start = beginRange[0];
       int[] endRange = mf.getMappedPositions(end, end);
+      if (beginRange == null || endRange == null)
+      {
+        // e.g. variant extending to stop codon so not mappable
+        return;
+      }
+      start = beginRange[0];
       end = endRange[endRange.length - 1];
     }
     StringBuilder desc = new StringBuilder();
index 0cfc380..337ac1a 100644 (file)
@@ -648,4 +648,67 @@ public class AlignedCodonFrameTest
     expected.addResult(dna1.getDatasetSequence(),  17, 18);
     assertEquals(sr, expected);
   }
+
+  @Test(groups = { "Functional" })
+  public void testGetCoveringCodonMapping()
+  {
+    SequenceI dna = new Sequence("dna/10-30", "acttcaATGGCGGACtaattt");
+    // CDS sequence with its own dataset sequence (JAL-3763)
+    SequenceI cds = new Sequence("cds/1-9", "-A--TGGC-GGAC");
+    cds.createDatasetSequence();
+    SequenceI pep = new Sequence("pep/1-3", "MAD");
+    
+    /*
+     * with null argument or no mappings
+     */
+    AlignedCodonFrame acf = new AlignedCodonFrame();
+    assertNull(acf.getCoveringCodonMapping(null));
+    assertNull(acf.getCoveringCodonMapping(dna));
+    assertNull(acf.getCoveringCodonMapping(pep));
+  
+    /*
+     * with a non-covering mapping e.g. overlapping exon
+     */
+    MapList map = new MapList(new int[] { 16, 18 }, new int[] {
+        1, 1 }, 3, 1);
+    acf.addMap(dna, pep, map);
+    assertNull(acf.getCoveringCodonMapping(dna));
+    assertNull(acf.getCoveringCodonMapping(pep));
+    
+    acf = new AlignedCodonFrame();
+    MapList map2 = new MapList(new int[] { 13, 18 }, new int[] {
+        2, 2 }, 3, 1);
+    acf.addMap(dna, pep, map2);
+    assertNull(acf.getCoveringCodonMapping(dna));
+    assertNull(acf.getCoveringCodonMapping(pep));
+    
+    /*
+     * with a covering mapping from CDS (dataset) to protein
+     */
+    acf = new AlignedCodonFrame();
+    MapList map3 = new MapList(new int[] { 1, 9 }, new int[] {
+        1, 3 }, 3, 1);
+    acf.addMap(cds.getDatasetSequence(), pep, map3);
+    assertNull(acf.getCoveringCodonMapping(dna));
+    SequenceToSequenceMapping mapping = acf.getCoveringCodonMapping(pep);
+    assertNotNull(mapping);
+    SequenceToSequenceMapping mapping2 = acf.getCoveringCodonMapping(cds.getDatasetSequence());
+    assertSame(mapping, mapping2);
+    
+    /*
+     * with a mapping that extends to stop codon
+     * (EMBL CDS location often includes the stop codon)
+     * - getCoveringCodonMapping is lenient (doesn't require exact length match)
+     */
+    SequenceI cds2 = new Sequence("cds/1-12", "-A--TGGC-GGACTAA");
+    cds2.createDatasetSequence();
+    acf = new AlignedCodonFrame();
+    MapList map4 = new MapList(new int[] { 1, 12 }, new int[] {
+        1, 3 }, 3, 1);
+    acf.addMap(cds2, pep, map4);
+    mapping = acf.getCoveringCodonMapping(cds2.getDatasetSequence());
+    assertNotNull(mapping);
+    mapping2 = acf.getCoveringCodonMapping(pep);
+    assertSame(mapping, mapping2);
+  }
 }