JAL-2897 generate peptide variants for synonymous codon variants
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 30 Jan 2018 15:34:48 +0000 (15:34 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 30 Jan 2018 15:34:48 +0000 (15:34 +0000)
src/jalview/analysis/AlignmentUtils.java
src/jalview/gui/CrossRefAction.java
src/jalview/io/gff/SequenceOntologyI.java
test/jalview/analysis/AlignmentUtilsTests.java
test/jalview/io/vcf/VCFLoaderTest.java

index 9278361..3d22115 100644 (file)
@@ -2428,10 +2428,14 @@ public class AlignmentUtils
         {
           for (String base : alleles.split(","))
           {
-            String codon = base + base2 + base3;
-            if (addPeptideVariant(peptide, peptidePos, residue, var, codon))
+            if (!base1.equals(base))
             {
-              count++;
+              String codon = base + base2 + base3;
+              if (addPeptideVariant(peptide, peptidePos, residue, var,
+                      codon))
+              {
+                count++;
+              }
             }
           }
         }
@@ -2450,10 +2454,14 @@ public class AlignmentUtils
         {
           for (String base : alleles.split(","))
           {
-            String codon = base1 + base + base3;
-            if (addPeptideVariant(peptide, peptidePos, residue, var, codon))
+            if (!base2.equals(base))
             {
-              count++;
+              String codon = base1 + base + base3;
+              if (addPeptideVariant(peptide, peptidePos, residue, var,
+                      codon))
+              {
+                count++;
+              }
             }
           }
         }
@@ -2472,10 +2480,14 @@ public class AlignmentUtils
         {
           for (String base : alleles.split(","))
           {
-            String codon = base1 + base2 + base;
-            if (addPeptideVariant(peptide, peptidePos, residue, var, codon))
+            if (!base3.equals(base))
             {
-              count++;
+              String codon = base1 + base2 + base;
+              if (addPeptideVariant(peptide, peptidePos, residue, var,
+                      codon))
+              {
+                count++;
+              }
             }
           }
         }
@@ -2507,57 +2519,67 @@ public class AlignmentUtils
      * e.g. multibase variants or HGMD_MUTATION etc
      * are currently ignored here
      */
-    String trans = codon.contains("-") ? "-"
+    String trans = codon.contains("-") ? null
             : (codon.length() > CODON_LENGTH ? null
                     : ResidueProperties.codonTranslate(codon));
-    if (trans != null && !trans.equals(residue))
+    if (trans == null)
+    {
+      return false;
+    }
+    String desc = codon;
+    String featureType = "";
+    if (trans.equals(residue))
+    {
+      featureType = SequenceOntologyI.SYNONYMOUS_VARIANT;
+    }
+    else
     {
       String residue3Char = StringUtils
               .toSentenceCase(ResidueProperties.aa2Triplet.get(residue));
       String trans3Char = StringUtils
               .toSentenceCase(ResidueProperties.aa2Triplet.get(trans));
-      String desc = "p." + residue3Char + peptidePos + trans3Char;
-      SequenceFeature sf = new SequenceFeature(
-              SequenceOntologyI.SEQUENCE_VARIANT, desc, peptidePos,
-              peptidePos, var.getSource());
-      StringBuilder attributes = new StringBuilder(32);
-      String id = (String) var.variant.getValue(ID);
-      if (id != null)
-      {
-        if (id.startsWith(SEQUENCE_VARIANT))
-        {
-          id = id.substring(SEQUENCE_VARIANT.length());
-        }
-        sf.setValue(ID, id);
-        attributes.append(ID).append("=").append(id);
-        // TODO handle other species variants JAL-2064
-        StringBuilder link = new StringBuilder(32);
-        try
-        {
-          link.append(desc).append(" ").append(id).append(
-                  "|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=")
-                  .append(URLEncoder.encode(id, "UTF-8"));
-          sf.addLink(link.toString());
-        } catch (UnsupportedEncodingException e)
-        {
-          // as if
-        }
-      }
-      String clinSig = (String) var.variant.getValue(CLINICAL_SIGNIFICANCE);
-      if (clinSig != null)
+      desc = "p." + residue3Char + peptidePos + trans3Char;
+      featureType = SequenceOntologyI.NONSYNONYMOUS_VARIANT;
+    }
+    SequenceFeature sf = new SequenceFeature(featureType, desc, peptidePos,
+            peptidePos, var.getSource());
+
+    StringBuilder attributes = new StringBuilder(32);
+    String id = (String) var.variant.getValue(ID);
+    if (id != null)
+    {
+      if (id.startsWith(SEQUENCE_VARIANT))
       {
-        sf.setValue(CLINICAL_SIGNIFICANCE, clinSig);
-        attributes.append(";").append(CLINICAL_SIGNIFICANCE).append("=")
-                .append(clinSig);
+        id = id.substring(SEQUENCE_VARIANT.length());
       }
-      peptide.addSequenceFeature(sf);
-      if (attributes.length() > 0)
+      sf.setValue(ID, id);
+      attributes.append(ID).append("=").append(id);
+      // TODO handle other species variants JAL-2064
+      StringBuilder link = new StringBuilder(32);
+      try
+      {
+        link.append(desc).append(" ").append(id).append(
+                "|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=")
+                .append(URLEncoder.encode(id, "UTF-8"));
+        sf.addLink(link.toString());
+      } catch (UnsupportedEncodingException e)
       {
-        sf.setAttributes(attributes.toString());
+        // as if
       }
-      return true;
     }
-    return false;
+    String clinSig = (String) var.variant.getValue(CLINICAL_SIGNIFICANCE);
+    if (clinSig != null)
+    {
+      sf.setValue(CLINICAL_SIGNIFICANCE, clinSig);
+      attributes.append(";").append(CLINICAL_SIGNIFICANCE).append("=")
+              .append(clinSig);
+    }
+    peptide.addSequenceFeature(sf);
+    if (attributes.length() > 0)
+    {
+      sf.setAttributes(attributes.toString());
+    }
+    return true;
   }
 
   /**
index 285e574..85f2498 100644 (file)
@@ -176,10 +176,14 @@ public class CrossRefAction implements Runnable
       /*
        * copy feature rendering settings to split frame
        */
-      newFrame.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
-              .transferSettings(myFeatureStyling);
-      copyThis.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
-              .transferSettings(myFeatureStyling);
+      FeatureRenderer fr1 = newFrame.alignPanel.getSeqPanel().seqCanvas
+              .getFeatureRenderer();
+      fr1.transferSettings(myFeatureStyling);
+      fr1.findAllFeatures(true);
+      FeatureRenderer fr2 = copyThis.alignPanel.getSeqPanel().seqCanvas
+              .getFeatureRenderer();
+      fr2.transferSettings(myFeatureStyling);
+      fr2.findAllFeatures(true);
 
       /*
        * apply 'database source' feature configuration
index c0570e0..10ca7ec 100644 (file)
@@ -42,6 +42,12 @@ public interface SequenceOntologyI
   // SO:0001060
   public static final String SEQUENCE_VARIANT = "sequence_variant";
 
+  // SO:0001819
+  public static final String SYNONYMOUS_VARIANT = "synonymous_variant";
+
+  // SO:0001992
+  public static final String NONSYNONYMOUS_VARIANT = "nonsynonymous_variant";
+
   // SO:0000147
   public static final String EXON = "exon";
 
index 1bff8bf..3e8390f 100644 (file)
@@ -263,14 +263,14 @@ public class AlignmentUtilsTests
   @Test(groups = { "Functional" })
   public void testMapProteinAlignmentToCdna_noXrefs() throws IOException
   {
-    List<SequenceI> protseqs = new ArrayList<SequenceI>();
+    List<SequenceI> protseqs = new ArrayList<>();
     protseqs.add(new Sequence("UNIPROT|V12345", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12346", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12347", "SAR"));
     AlignmentI protein = new Alignment(protseqs.toArray(new SequenceI[3]));
     protein.setDataset(null);
 
-    List<SequenceI> dnaseqs = new ArrayList<SequenceI>();
+    List<SequenceI> dnaseqs = new ArrayList<>();
     dnaseqs.add(new Sequence("EMBL|A11111", "TCAGCACGC")); // = SAR
     dnaseqs.add(new Sequence("EMBL|A22222", "GAGATACAA")); // = EIQ
     dnaseqs.add(new Sequence("EMBL|A33333", "GAAATCCAG")); // = EIQ
@@ -507,7 +507,7 @@ public class AlignmentUtilsTests
     acf.addMap(dna1.getDatasetSequence(), prot1.getDatasetSequence(), map);
     acf.addMap(dna2.getDatasetSequence(), prot2.getDatasetSequence(), map);
     acf.addMap(dna3.getDatasetSequence(), prot3.getDatasetSequence(), map);
-    ArrayList<AlignedCodonFrame> acfs = new ArrayList<AlignedCodonFrame>();
+    ArrayList<AlignedCodonFrame> acfs = new ArrayList<>();
     acfs.add(acf);
     protein.setCodonFrames(acfs);
 
@@ -605,14 +605,14 @@ public class AlignmentUtilsTests
   public void testMapProteinAlignmentToCdna_withStartAndStopCodons()
           throws IOException
   {
-    List<SequenceI> protseqs = new ArrayList<SequenceI>();
+    List<SequenceI> protseqs = new ArrayList<>();
     protseqs.add(new Sequence("UNIPROT|V12345", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12346", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12347", "SAR"));
     AlignmentI protein = new Alignment(protseqs.toArray(new SequenceI[3]));
     protein.setDataset(null);
 
-    List<SequenceI> dnaseqs = new ArrayList<SequenceI>();
+    List<SequenceI> dnaseqs = new ArrayList<>();
     // start + SAR:
     dnaseqs.add(new Sequence("EMBL|A11111", "ATGTCAGCACGC"));
     // = EIQ + stop
@@ -697,14 +697,14 @@ public class AlignmentUtilsTests
   @Test(groups = { "Functional" })
   public void testMapProteinAlignmentToCdna_withXrefs() throws IOException
   {
-    List<SequenceI> protseqs = new ArrayList<SequenceI>();
+    List<SequenceI> protseqs = new ArrayList<>();
     protseqs.add(new Sequence("UNIPROT|V12345", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12346", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12347", "SAR"));
     AlignmentI protein = new Alignment(protseqs.toArray(new SequenceI[3]));
     protein.setDataset(null);
 
-    List<SequenceI> dnaseqs = new ArrayList<SequenceI>();
+    List<SequenceI> dnaseqs = new ArrayList<>();
     dnaseqs.add(new Sequence("EMBL|A11111", "TCAGCACGC")); // = SAR
     dnaseqs.add(new Sequence("EMBL|A22222", "ATGGAGATACAA")); // = start + EIQ
     dnaseqs.add(new Sequence("EMBL|A33333", "GAAATCCAG")); // = EIQ
@@ -774,14 +774,14 @@ public class AlignmentUtilsTests
   public void testMapProteinAlignmentToCdna_prioritiseXrefs()
           throws IOException
   {
-    List<SequenceI> protseqs = new ArrayList<SequenceI>();
+    List<SequenceI> protseqs = new ArrayList<>();
     protseqs.add(new Sequence("UNIPROT|V12345", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12346", "EIQ"));
     AlignmentI protein = new Alignment(
             protseqs.toArray(new SequenceI[protseqs.size()]));
     protein.setDataset(null);
 
-    List<SequenceI> dnaseqs = new ArrayList<SequenceI>();
+    List<SequenceI> dnaseqs = new ArrayList<>();
     dnaseqs.add(new Sequence("EMBL|A11111", "GAAATCCAG")); // = EIQ
     dnaseqs.add(new Sequence("EMBL|A22222", "GAAATTCAG")); // = EIQ
     AlignmentI cdna = new Alignment(dnaseqs.toArray(new SequenceI[dnaseqs
@@ -848,8 +848,8 @@ public class AlignmentUtilsTests
     al.addAnnotation(ann4); // Temp for seq1
     al.addAnnotation(ann5); // Temp for seq2
     al.addAnnotation(ann6); // Temp for no sequence
-    List<String> types = new ArrayList<String>();
-    List<SequenceI> scope = new ArrayList<SequenceI>();
+    List<String> types = new ArrayList<>();
+    List<SequenceI> scope = new ArrayList<>();
 
     /*
      * Set all sequence related Structure to hidden (ann1, ann2)
@@ -1783,7 +1783,7 @@ public class AlignmentUtilsTests
     map = new MapList(new int[] { 9, 11 }, new int[] { 2, 2 }, 3, 1);
     acf.addMap(dna3.getDatasetSequence(), prot3.getDatasetSequence(), map);
 
-    ArrayList<AlignedCodonFrame> acfs = new ArrayList<AlignedCodonFrame>();
+    ArrayList<AlignedCodonFrame> acfs = new ArrayList<>();
     acfs.add(acf);
     protein.setCodonFrames(acfs);
 
@@ -1932,6 +1932,7 @@ public class AlignmentUtilsTests
     sf6.setValue("alleles", "g, a"); // should force to upper-case
     sf6.setValue("ID", "sequence_variant:rs758803216");
     dna.addSequenceFeature(sf6);
+
     SequenceFeature sf7 = new SequenceFeature("sequence_variant", "", 15,
             15, 0f, null);
     sf7.setValue("alleles", "A, T");
@@ -2021,6 +2022,7 @@ public class AlignmentUtilsTests
      * variants:
      *           GAA -> E             source: Ensembl
      *           CAA -> Q             source: dbSNP
+     *           TAA -> STOP          source: dnSNP
      *           AAG synonymous       source: COSMIC
      *           AAT -> N             source: Ensembl
      *           ...TTC synonymous    source: dbSNP
@@ -2036,39 +2038,50 @@ public class AlignmentUtilsTests
     String ensembl = "Ensembl";
     String dbSnp = "dbSNP";
     String cosmic = "COSMIC";
+
     SequenceFeature sf1 = new SequenceFeature("sequence_variant", "", 1, 1,
             0f, ensembl);
-    sf1.setValue("alleles", "A,G"); // GAA -> E
+    sf1.setValue("alleles", "A,G"); // AAA -> GAA -> K/E
     sf1.setValue("ID", "var1.125A>G");
+
     SequenceFeature sf2 = new SequenceFeature("sequence_variant", "", 1, 1,
             0f, dbSnp);
-    sf2.setValue("alleles", "A,C"); // CAA -> Q
+    sf2.setValue("alleles", "A,C"); // AAA -> CAA -> K/Q
     sf2.setValue("ID", "var2");
     sf2.setValue("clinical_significance", "Dodgy");
-    SequenceFeature sf3 = new SequenceFeature("sequence_variant", "", 3, 3,
-            0f, cosmic);
-    sf3.setValue("alleles", "A,G"); // synonymous
+
+    SequenceFeature sf3 = new SequenceFeature("sequence_variant", "", 1, 1,
+            0f, dbSnp);
+    sf3.setValue("alleles", "A,T"); // AAA -> TAA -> stop codon
     sf3.setValue("ID", "var3");
-    sf3.setValue("clinical_significance", "None");
+    sf3.setValue("clinical_significance", "Bad");
+
     SequenceFeature sf4 = new SequenceFeature("sequence_variant", "", 3, 3,
+            0f, cosmic);
+    sf4.setValue("alleles", "A,G"); // AAA -> AAG synonymous
+    sf4.setValue("ID", "var4");
+    sf4.setValue("clinical_significance", "None");
+
+    SequenceFeature sf5 = new SequenceFeature("sequence_variant", "", 3, 3,
             0f, ensembl);
-    sf4.setValue("alleles", "A,T"); // AAT -> N
-    sf4.setValue("ID", "sequence_variant:var4"); // prefix gets stripped off
-    sf4.setValue("clinical_significance", "Benign");
-    SequenceFeature sf5 = new SequenceFeature("sequence_variant", "", 6, 6,
+    sf5.setValue("alleles", "A,T"); // AAA -> AAT -> K/N
+    sf5.setValue("ID", "sequence_variant:var5"); // prefix gets stripped off
+    sf5.setValue("clinical_significance", "Benign");
+
+    SequenceFeature sf6 = new SequenceFeature("sequence_variant", "", 6, 6,
             0f, dbSnp);
-    sf5.setValue("alleles", "T,C"); // synonymous
-    sf5.setValue("ID", "var5");
-    sf5.setValue("clinical_significance", "Bad");
-    SequenceFeature sf6 = new SequenceFeature("sequence_variant", "", 8, 8,
-            0f, cosmic);
-    sf6.setValue("alleles", "C,A,G"); // CAC,CGC -> H,R
+    sf6.setValue("alleles", "T,C"); // TTT -> TTC synonymous
     sf6.setValue("ID", "var6");
-    sf6.setValue("clinical_significance", "Good");
 
-    List<DnaVariant> codon1Variants = new ArrayList<DnaVariant>();
-    List<DnaVariant> codon2Variants = new ArrayList<DnaVariant>();
-    List<DnaVariant> codon3Variants = new ArrayList<DnaVariant>();
+    SequenceFeature sf7 = new SequenceFeature("sequence_variant", "", 8, 8,
+            0f, cosmic);
+    sf7.setValue("alleles", "C,A,G"); // CCC -> CAC,CGC -> P/H/R
+    sf7.setValue("ID", "var7");
+    sf7.setValue("clinical_significance", "Good");
+
+    List<DnaVariant> codon1Variants = new ArrayList<>();
+    List<DnaVariant> codon2Variants = new ArrayList<>();
+    List<DnaVariant> codon3Variants = new ArrayList<>();
     List<DnaVariant> codonVariants[] = new ArrayList[3];
     codonVariants[0] = codon1Variants;
     codonVariants[1] = codon2Variants;
@@ -2079,10 +2092,11 @@ public class AlignmentUtilsTests
      */
     codon1Variants.add(new DnaVariant("A", sf1));
     codon1Variants.add(new DnaVariant("A", sf2));
+    codon1Variants.add(new DnaVariant("A", sf3));
     codon2Variants.add(new DnaVariant("A"));
-    codon2Variants.add(new DnaVariant("A"));
-    codon3Variants.add(new DnaVariant("A", sf3));
+    // codon2Variants.add(new DnaVariant("A"));
     codon3Variants.add(new DnaVariant("A", sf4));
+    codon3Variants.add(new DnaVariant("A", sf5));
     AlignmentUtils.computePeptideVariants(peptide, 1, codonVariants);
 
     /*
@@ -2093,7 +2107,7 @@ public class AlignmentUtilsTests
     codon3Variants.clear();
     codon1Variants.add(new DnaVariant("T"));
     codon2Variants.add(new DnaVariant("T"));
-    codon3Variants.add(new DnaVariant("T", sf5));
+    codon3Variants.add(new DnaVariant("T", sf6));
     AlignmentUtils.computePeptideVariants(peptide, 2, codonVariants);
 
     /*
@@ -2103,7 +2117,7 @@ public class AlignmentUtilsTests
     codon2Variants.clear();
     codon3Variants.clear();
     codon1Variants.add(new DnaVariant("C"));
-    codon2Variants.add(new DnaVariant("C", sf6));
+    codon2Variants.add(new DnaVariant("C", sf7));
     codon3Variants.add(new DnaVariant("C"));
     AlignmentUtils.computePeptideVariants(peptide, 3, codonVariants);
 
@@ -2111,35 +2125,58 @@ public class AlignmentUtilsTests
      * verify added sequence features for
      * var1 K -> E Ensembl
      * var2 K -> Q dbSNP
-     * var4 K -> N Ensembl
-     * var6 P -> H COSMIC
-     * var6 P -> R COSMIC
+     * var3 K -> stop
+     * var4 synonymous
+     * var5 K -> N Ensembl
+     * var6 synonymous
+     * var7 P -> H COSMIC
+     * var8 P -> R COSMIC
      */
     List<SequenceFeature> sfs = peptide.getSequenceFeatures();
     SequenceFeatures.sortFeatures(sfs, true);
-    assertEquals(5, sfs.size());
+    assertEquals(8, sfs.size());
 
     /*
      * features are sorted by start position ascending, but in no
      * particular order where start positions match; asserts here
      * simply match the data returned (the order is not important)
      */
+    // AAA -> AAT -> K/N
     SequenceFeature sf = sfs.get(0);
     assertEquals(1, sf.getBegin());
     assertEquals(1, sf.getEnd());
+    assertEquals("nonsynonymous_variant", sf.getType());
     assertEquals("p.Lys1Asn", sf.getDescription());
-    assertEquals("var4", sf.getValue("ID"));
+    assertEquals("var5", sf.getValue("ID"));
     assertEquals("Benign", sf.getValue("clinical_significance"));
-    assertEquals("ID=var4;clinical_significance=Benign", sf.getAttributes());
+    assertEquals("ID=var5;clinical_significance=Benign",
+            sf.getAttributes());
     assertEquals(1, sf.links.size());
     assertEquals(
-            "p.Lys1Asn var4|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var4",
+            "p.Lys1Asn var5|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var5",
             sf.links.get(0));
     assertEquals(ensembl, sf.getFeatureGroup());
 
+    // AAA -> TAA -> stop codon
     sf = sfs.get(1);
     assertEquals(1, sf.getBegin());
     assertEquals(1, sf.getEnd());
+    assertEquals("nonsynonymous_variant", sf.getType());
+    assertEquals("p.Lys1null", sf.getDescription()); // stop codon badly handled
+    assertEquals("var3", sf.getValue("ID"));
+    assertEquals("Bad", sf.getValue("clinical_significance"));
+    assertEquals("ID=var3;clinical_significance=Bad", sf.getAttributes());
+    assertEquals(1, sf.links.size());
+    assertEquals(
+            "p.Lys1null var3|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var3",
+            sf.links.get(0));
+    assertEquals(dbSnp, sf.getFeatureGroup());
+
+    // AAA -> CAA -> K/Q
+    sf = sfs.get(2);
+    assertEquals(1, sf.getBegin());
+    assertEquals(1, sf.getEnd());
+    assertEquals("nonsynonymous_variant", sf.getType());
     assertEquals("p.Lys1Gln", sf.getDescription());
     assertEquals("var2", sf.getValue("ID"));
     assertEquals("Dodgy", sf.getValue("clinical_significance"));
@@ -2150,9 +2187,11 @@ public class AlignmentUtilsTests
             sf.links.get(0));
     assertEquals(dbSnp, sf.getFeatureGroup());
 
-    sf = sfs.get(2);
+    // AAA -> GAA -> K/E
+    sf = sfs.get(3);
     assertEquals(1, sf.getBegin());
     assertEquals(1, sf.getEnd());
+    assertEquals("nonsynonymous_variant", sf.getType());
     assertEquals("p.Lys1Glu", sf.getDescription());
     assertEquals("var1.125A>G", sf.getValue("ID"));
     assertNull(sf.getValue("clinical_significance"));
@@ -2164,30 +2203,64 @@ public class AlignmentUtilsTests
             sf.links.get(0));
     assertEquals(ensembl, sf.getFeatureGroup());
 
-    sf = sfs.get(3);
+    // AAA -> AAG synonymous
+    sf = sfs.get(4);
+    assertEquals(1, sf.getBegin());
+    assertEquals(1, sf.getEnd());
+    assertEquals("synonymous_variant", sf.getType());
+    assertEquals("AAG", sf.getDescription());
+    assertEquals("var4", sf.getValue("ID"));
+    assertEquals("None", sf.getValue("clinical_significance"));
+    assertEquals("ID=var4;clinical_significance=None", sf.getAttributes());
+    assertEquals(1, sf.links.size());
+    assertEquals(
+            "AAG var4|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var4",
+            sf.links.get(0));
+    assertEquals(cosmic, sf.getFeatureGroup());
+
+    // TTT -> TTC synonymous
+    sf = sfs.get(5);
+    assertEquals(2, sf.getBegin());
+    assertEquals(2, sf.getEnd());
+    assertEquals("synonymous_variant", sf.getType());
+    assertEquals("TTC", sf.getDescription());
+    assertEquals("var6", sf.getValue("ID"));
+    assertNull(sf.getValue("clinical_significance"));
+    assertEquals("ID=var6", sf.getAttributes());
+    assertEquals(1, sf.links.size());
+    assertEquals(
+            "TTC var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6",
+            sf.links.get(0));
+    assertEquals(dbSnp, sf.getFeatureGroup());
+
+    // var7 generates two distinct protein variant features (two alleles)
+    // CCC -> CGC -> P/R
+    sf = sfs.get(6);
     assertEquals(3, sf.getBegin());
     assertEquals(3, sf.getEnd());
+    assertEquals("nonsynonymous_variant", sf.getType());
     assertEquals("p.Pro3Arg", sf.getDescription());
-    assertEquals("var6", sf.getValue("ID"));
+    assertEquals("var7", sf.getValue("ID"));
     assertEquals("Good", sf.getValue("clinical_significance"));
-    assertEquals("ID=var6;clinical_significance=Good", sf.getAttributes());
+    assertEquals("ID=var7;clinical_significance=Good", sf.getAttributes());
     assertEquals(1, sf.links.size());
     assertEquals(
-            "p.Pro3Arg var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6",
+            "p.Pro3Arg var7|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var7",
             sf.links.get(0));
     assertEquals(cosmic, sf.getFeatureGroup());
 
-    // var5 generates two distinct protein variant features
-    sf = sfs.get(4);
+    // CCC -> CAC -> P/H
+    sf = sfs.get(7);
     assertEquals(3, sf.getBegin());
     assertEquals(3, sf.getEnd());
+    assertEquals("nonsynonymous_variant", sf.getType());
     assertEquals("p.Pro3His", sf.getDescription());
-    assertEquals("var6", sf.getValue("ID"));
+    assertEquals("var7", sf.getValue("ID"));
     assertEquals("Good", sf.getValue("clinical_significance"));
-    assertEquals("ID=var6;clinical_significance=Good", sf.getAttributes());
+    assertEquals("ID=var7;clinical_significance=Good", sf.getAttributes());
     assertEquals(1, sf.links.size());
     assertEquals(
-            "p.Pro3His var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6",
+            "p.Pro3His var7|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var7",
             sf.links.get(0));
     assertEquals(cosmic, sf.getFeatureGroup());
   }
@@ -2308,7 +2381,7 @@ public class AlignmentUtilsTests
     seq1.createDatasetSequence();
     Mapping mapping = new Mapping(seq1, new MapList(
             new int[] { 3, 6, 9, 10 }, new int[] { 1, 6 }, 1, 1));
-    Map<Integer, Map<SequenceI, Character>> map = new TreeMap<Integer, Map<SequenceI, Character>>();
+    Map<Integer, Map<SequenceI, Character>> map = new TreeMap<>();
     AlignmentUtils.addMappedPositions(seq1, from, mapping, map);
 
     /*
@@ -2340,7 +2413,7 @@ public class AlignmentUtilsTests
     seq1.createDatasetSequence();
     Mapping mapping = new Mapping(seq1, new MapList(
             new int[] { 3, 6, 9, 10 }, new int[] { 1, 6 }, 1, 1));
-    Map<Integer, Map<SequenceI, Character>> map = new TreeMap<Integer, Map<SequenceI, Character>>();
+    Map<Integer, Map<SequenceI, Character>> map = new TreeMap<>();
     AlignmentUtils.addMappedPositions(seq1, from, mapping, map);
 
     /*
index a02cc5a..7099282 100644 (file)
@@ -170,7 +170,7 @@ public class VCFLoaderTest
     assertEquals(sf.getFeatureGroup(), "VCF");
     assertEquals(sf.getBegin(), 1);
     assertEquals(sf.getEnd(), 1);
-    assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
+    assertEquals(sf.getType(), SequenceOntologyI.NONSYNONYMOUS_VARIANT);
     assertEquals(sf.getDescription(), "p.Ser1Thr");
   }
 
@@ -425,7 +425,7 @@ public class VCFLoaderTest
     assertEquals(sf.getFeatureGroup(), "VCF");
     assertEquals(sf.getBegin(), 6);
     assertEquals(sf.getEnd(), 6);
-    assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
+    assertEquals(sf.getType(), SequenceOntologyI.NONSYNONYMOUS_VARIANT);
     assertEquals(sf.getDescription(), "p.Ala6Gly");
   }
 
@@ -570,12 +570,19 @@ public class VCFLoaderTest
       }
     }
     List<SequenceFeature> proteinFeatures = peptide.getSequenceFeatures();
-    assertEquals(proteinFeatures.size(), 1);
+    SequenceFeatures.sortFeatures(proteinFeatures, true);
+    assertEquals(proteinFeatures.size(), 2);
     sf = proteinFeatures.get(0);
     assertEquals(sf.getFeatureGroup(), "VCF");
+    assertEquals(sf.getBegin(), 1);
+    assertEquals(sf.getEnd(), 1);
+    assertEquals(sf.getType(), SequenceOntologyI.SYNONYMOUS_VARIANT);
+    assertEquals(sf.getDescription(), "AGT");
+    sf = proteinFeatures.get(1);
+    assertEquals(sf.getFeatureGroup(), "VCF");
     assertEquals(sf.getBegin(), 4);
     assertEquals(sf.getEnd(), 4);
-    assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
+    assertEquals(sf.getType(), SequenceOntologyI.NONSYNONYMOUS_VARIANT);
     assertEquals(sf.getDescription(), "p.Glu4Gly");
 
     /*