Merge remote-tracking branch 'origin/features/JAL-2814ftsHelp' into merge/JAL-2814
[jalview.git] / test / jalview / io / vcf / VCFLoaderTest.java
index 246337d..58c73dd 100644 (file)
@@ -75,17 +75,18 @@ public class VCFLoaderTest
     Cache.loadProperties("test/jalview/io/testProps.jvprops");
     Cache.setProperty("VCF_FIELDS", ".*");
     Cache.setProperty("VEP_FIELDS", ".*");
+    Cache.initLogger();
   }
 
   @Test(groups = "Functional")
   public void testDoLoad() throws IOException
   {
     AlignmentI al = buildAlignment();
-    VCFLoader loader = new VCFLoader(al);
 
     File f = makeVcf();
+    VCFLoader loader = new VCFLoader(f.getPath());
 
-    loader.doLoad(f.getPath(), null);
+    loader.doLoad(al.getSequencesArray(), null);
 
     /*
      * verify variant feature(s) added to gene
@@ -102,7 +103,9 @@ public class VCFLoaderTest
     assertEquals(sf.getFeatureGroup(), "VCF");
     assertEquals(sf.getBegin(), 2);
     assertEquals(sf.getEnd(), 2);
-    assertEquals(sf.getScore(), 4.0e-03, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 4.0e-03,
+            DELTA);
     assertEquals(sf.getValue(Gff3Helper.ALLELES), "A,C");
     assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
     sf = geneFeatures.get(1);
@@ -110,7 +113,9 @@ public class VCFLoaderTest
     assertEquals(sf.getBegin(), 2);
     assertEquals(sf.getEnd(), 2);
     assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
-    assertEquals(sf.getScore(), 5.0e-03, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 5.0e-03,
+            DELTA);
     assertEquals(sf.getValue(Gff3Helper.ALLELES), "A,T");
 
     sf = geneFeatures.get(2);
@@ -118,7 +123,9 @@ public class VCFLoaderTest
     assertEquals(sf.getBegin(), 4);
     assertEquals(sf.getEnd(), 4);
     assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
-    assertEquals(sf.getScore(), 2.0e-03, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 2.0e-03,
+            DELTA);
     assertEquals(sf.getValue(Gff3Helper.ALLELES), "G,C");
 
     sf = geneFeatures.get(3);
@@ -126,7 +133,9 @@ public class VCFLoaderTest
     assertEquals(sf.getBegin(), 4);
     assertEquals(sf.getEnd(), 4);
     assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
-    assertEquals(sf.getScore(), 3.0e-03, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 3.0e-03,
+            DELTA);
     assertEquals(sf.getValue(Gff3Helper.ALLELES), "G,GA");
 
     /*
@@ -140,14 +149,18 @@ public class VCFLoaderTest
     assertEquals(sf.getBegin(), 2);
     assertEquals(sf.getEnd(), 2);
     assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
-    assertEquals(sf.getScore(), 2.0e-03, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 2.0e-03,
+            DELTA);
     assertEquals(sf.getValue(Gff3Helper.ALLELES), "G,C");
     sf = transcriptFeatures.get(1);
     assertEquals(sf.getFeatureGroup(), "VCF");
     assertEquals(sf.getBegin(), 2);
     assertEquals(sf.getEnd(), 2);
     assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
-    assertEquals(sf.getScore(), 3.0e-03, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 3.0e-03,
+            DELTA);
     assertEquals(sf.getValue(Gff3Helper.ALLELES), "G,GA");
 
     /*
@@ -169,7 +182,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");
   }
 
@@ -313,77 +326,109 @@ public class VCFLoaderTest
   {
     AlignmentI al = buildAlignment();
 
-    VCFLoader loader = new VCFLoader(al);
-
     File f = makeVcf();
 
-    loader.doLoad(f.getPath(), null);
+    VCFLoader loader = new VCFLoader(f.getPath());
+
+    loader.doLoad(al.getSequencesArray(), null);
 
     /*
      * verify variant feature(s) added to gene2
-     * gene/1-25 maps to chromosome 45051634- reverse strand
-     * variants A/T, A/C at 45051611 and G/GA,G/C at 45051613 map to
-     * T/A, T/G and C/TC,C/G at gene positions 24 and 22 respectively
+     * gene2/1-25 maps to chromosome 45051634- reverse strand
      */
     List<SequenceFeature> geneFeatures = al.getSequenceAt(2)
             .getSequenceFeatures();
     SequenceFeatures.sortFeatures(geneFeatures, true);
     assertEquals(geneFeatures.size(), 4);
-    SequenceFeature sf = geneFeatures.get(0);
-    assertEquals(sf.getFeatureGroup(), "VCF");
-    assertEquals(sf.getBegin(), 22);
-    assertEquals(sf.getEnd(), 22);
-    assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
-    assertEquals(sf.getScore(), 2.0e-03, DELTA);
-    assertEquals("C,G", sf.getValue(Gff3Helper.ALLELES));
 
-    sf = geneFeatures.get(1);
+    /*
+     * variant A/T at 45051611 maps to T/A at gene position 24
+     */
+    SequenceFeature sf = geneFeatures.get(3);
     assertEquals(sf.getFeatureGroup(), "VCF");
-    assertEquals(sf.getBegin(), 22);
-    assertEquals(sf.getEnd(), 22);
+    assertEquals(sf.getBegin(), 24);
+    assertEquals(sf.getEnd(), 24);
     assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
-    assertEquals(sf.getScore(), 3.0e-03, DELTA);
-    assertEquals("C,TC", sf.getValue(Gff3Helper.ALLELES));
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 5.0e-03,
+            DELTA);
+    assertEquals(sf.getValue(Gff3Helper.ALLELES), "T,A");
 
+    /*
+     * variant A/C at 45051611 maps to T/G at gene position 24
+     */
     sf = geneFeatures.get(2);
     assertEquals(sf.getFeatureGroup(), "VCF");
     assertEquals(sf.getBegin(), 24);
     assertEquals(sf.getEnd(), 24);
     assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
-    assertEquals(sf.getScore(), 4.0e-03, DELTA);
-    assertEquals("T,G", sf.getValue(Gff3Helper.ALLELES));
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 4.0e-03,
+            DELTA);
+    assertEquals(sf.getValue(Gff3Helper.ALLELES), "T,G");
 
-    sf = geneFeatures.get(3);
+    /*
+     * variant G/C at 45051613 maps to C/G at gene position 22
+     */
+    sf = geneFeatures.get(1);
     assertEquals(sf.getFeatureGroup(), "VCF");
-    assertEquals(sf.getBegin(), 24);
-    assertEquals(sf.getEnd(), 24);
+    assertEquals(sf.getBegin(), 22);
+    assertEquals(sf.getEnd(), 22);
     assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
-    assertEquals(sf.getScore(), 5.0e-03, DELTA);
-    assertEquals("T,A", sf.getValue(Gff3Helper.ALLELES));
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 2.0e-03,
+            DELTA);
+    assertEquals(sf.getValue(Gff3Helper.ALLELES), "C,G");
 
     /*
-     * verify variant feature(s) added to transcript2
-     * variants G/GA,G/C at position 22 of gene overlap and map to
-     * C/TC,C/G at position 17 of transcript
+     * insertion G/GA at 45051613 maps to an insertion at
+     * the preceding position (21) on reverse strand gene
+     * reference: CAAGC -> GCTTG/21-25
+     * genomic variant: CAAGAC (G/GA)
+     * gene variant: GTCTTG (G/GT at 21)
+     */
+    sf = geneFeatures.get(0);
+    assertEquals(sf.getFeatureGroup(), "VCF");
+    assertEquals(sf.getBegin(), 21);
+    assertEquals(sf.getEnd(), 21);
+    assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 3.0e-03,
+            DELTA);
+    assertEquals(sf.getValue(Gff3Helper.ALLELES), "G,GT");
+
+    /*
+     * verify 2 variant features added to transcript2
      */
     List<SequenceFeature> transcriptFeatures = al.getSequenceAt(3)
             .getSequenceFeatures();
     assertEquals(transcriptFeatures.size(), 2);
+
+    /*
+     * insertion G/GT at position 21 of gene maps to position 16 of transcript
+     */
     sf = transcriptFeatures.get(0);
     assertEquals(sf.getFeatureGroup(), "VCF");
-    assertEquals(sf.getBegin(), 17);
-    assertEquals(sf.getEnd(), 17);
+    assertEquals(sf.getBegin(), 16);
+    assertEquals(sf.getEnd(), 16);
     assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
-    assertEquals(sf.getScore(), 2.0e-03, DELTA);
-    assertEquals("C,G", sf.getValue(Gff3Helper.ALLELES));
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 3.0e-03,
+            DELTA);
+    assertEquals(sf.getValue(Gff3Helper.ALLELES), "G,GT");
 
+    /*
+     * SNP C/G at position 22 of gene maps to position 17 of transcript
+     */
     sf = transcriptFeatures.get(1);
     assertEquals(sf.getFeatureGroup(), "VCF");
     assertEquals(sf.getBegin(), 17);
     assertEquals(sf.getEnd(), 17);
     assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
-    assertEquals(sf.getScore(), 3.0e-03, DELTA);
-    assertEquals("C,TC", sf.getValue(Gff3Helper.ALLELES));
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 2.0e-03,
+            DELTA);
+    assertEquals(sf.getValue(Gff3Helper.ALLELES), "C,G");
 
     /*
      * verify variant feature(s) computed and added to protein
@@ -404,7 +449,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");
   }
 
@@ -420,7 +465,7 @@ public class VCFLoaderTest
   {
     AlignmentI al = buildAlignment();
 
-    VCFLoader loader = new VCFLoader(al);
+    VCFLoader loader = new VCFLoader("test/jalview/io/vcf/testVcf.vcf");
 
     /*
      * VCF data file with variants at gene3 positions
@@ -430,7 +475,7 @@ public class VCFLoaderTest
      * 13 C/G, C/T
      * 17 A/AC (insertion), A/G
      */
-    loader.doLoad("test/jalview/io/vcf/testVcf.dat", null);
+    loader.doLoad(al.getSequencesArray(), null);
 
     /*
      * verify variant feature(s) added to gene3
@@ -442,7 +487,8 @@ public class VCFLoaderTest
     SequenceFeature sf = geneFeatures.get(0);
     assertEquals(sf.getBegin(), 1);
     assertEquals(sf.getEnd(), 1);
-    assertEquals(sf.getScore(), 0.1f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.1f, DELTA);
     assertEquals(sf.getValue("alleles"), "C,A");
     // gene features include Consequence for all transcripts
     Map map = (Map) sf.getValue("CSQ");
@@ -451,7 +497,8 @@ public class VCFLoaderTest
     sf = geneFeatures.get(1);
     assertEquals(sf.getBegin(), 5);
     assertEquals(sf.getEnd(), 5);
-    assertEquals(sf.getScore(), 0.2f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.2f, DELTA);
     assertEquals(sf.getValue("alleles"), "C,T");
     map = (Map) sf.getValue("CSQ");
     assertEquals(map.size(), 9);
@@ -459,7 +506,8 @@ public class VCFLoaderTest
     sf = geneFeatures.get(2);
     assertEquals(sf.getBegin(), 9);
     assertEquals(sf.getEnd(), 11); // deletion over 3 positions
-    assertEquals(sf.getScore(), 0.3f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.3f, DELTA);
     assertEquals(sf.getValue("alleles"), "CGG,C");
     map = (Map) sf.getValue("CSQ");
     assertEquals(map.size(), 9);
@@ -467,7 +515,8 @@ public class VCFLoaderTest
     sf = geneFeatures.get(3);
     assertEquals(sf.getBegin(), 13);
     assertEquals(sf.getEnd(), 13);
-    assertEquals(sf.getScore(), 0.5f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.5f, DELTA);
     assertEquals(sf.getValue("alleles"), "C,T");
     map = (Map) sf.getValue("CSQ");
     assertEquals(map.size(), 9);
@@ -475,7 +524,8 @@ public class VCFLoaderTest
     sf = geneFeatures.get(4);
     assertEquals(sf.getBegin(), 13);
     assertEquals(sf.getEnd(), 13);
-    assertEquals(sf.getScore(), 0.4f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.4f, DELTA);
     assertEquals(sf.getValue("alleles"), "C,G");
     map = (Map) sf.getValue("CSQ");
     assertEquals(map.size(), 9);
@@ -483,7 +533,8 @@ public class VCFLoaderTest
     sf = geneFeatures.get(5);
     assertEquals(sf.getBegin(), 17);
     assertEquals(sf.getEnd(), 17);
-    assertEquals(sf.getScore(), 0.7f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.7f, DELTA);
     assertEquals(sf.getValue("alleles"), "A,G");
     map = (Map) sf.getValue("CSQ");
     assertEquals(map.size(), 9);
@@ -491,7 +542,8 @@ public class VCFLoaderTest
     sf = geneFeatures.get(6);
     assertEquals(sf.getBegin(), 17);
     assertEquals(sf.getEnd(), 17); // insertion
-    assertEquals(sf.getScore(), 0.6f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.6f, DELTA);
     assertEquals(sf.getValue("alleles"), "A,AC");
     map = (Map) sf.getValue("CSQ");
     assertEquals(map.size(), 9);
@@ -509,7 +561,8 @@ public class VCFLoaderTest
     sf = transcriptFeatures.get(0);
     assertEquals(sf.getBegin(), 3);
     assertEquals(sf.getEnd(), 3);
-    assertEquals(sf.getScore(), 0.2f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.2f, DELTA);
     assertEquals(sf.getValue("alleles"), "C,T");
     // transcript features only have Consequence for that transcripts
     map = (Map) sf.getValue("CSQ");
@@ -519,7 +572,8 @@ public class VCFLoaderTest
     sf = transcriptFeatures.get(1);
     assertEquals(sf.getBegin(), 11);
     assertEquals(sf.getEnd(), 11);
-    assertEquals(sf.getScore(), 0.7f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.7f, DELTA);
     assertEquals(sf.getValue("alleles"), "A,G");
     assertEquals(map.size(), 9);
     assertEquals(sf.getValueAsString("CSQ", "Feature"), "transcript3");
@@ -527,7 +581,8 @@ public class VCFLoaderTest
     sf = transcriptFeatures.get(2);
     assertEquals(sf.getBegin(), 11);
     assertEquals(sf.getEnd(), 11);
-    assertEquals(sf.getScore(), 0.6f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.6f, DELTA);
     assertEquals(sf.getValue("alleles"), "A,AC");
     assertEquals(map.size(), 9);
     assertEquals(sf.getValueAsString("CSQ", "Feature"), "transcript3");
@@ -549,12 +604,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(), "agC/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");
 
     /*
@@ -567,7 +629,8 @@ public class VCFLoaderTest
     sf = transcriptFeatures.get(0);
     assertEquals(sf.getBegin(), 7);
     assertEquals(sf.getEnd(), 7);
-    assertEquals(sf.getScore(), 0.5f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.5f, DELTA);
     assertEquals(sf.getValue("alleles"), "C,T");
     assertEquals(map.size(), 9);
     assertEquals(sf.getValueAsString("CSQ", "Feature"), "transcript4");
@@ -575,7 +638,8 @@ public class VCFLoaderTest
     sf = transcriptFeatures.get(1);
     assertEquals(sf.getBegin(), 7);
     assertEquals(sf.getEnd(), 7);
-    assertEquals(sf.getScore(), 0.4f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.4f, DELTA);
     assertEquals(sf.getValue("alleles"), "C,G");
     assertEquals(map.size(), 9);
     assertEquals(sf.getValueAsString("CSQ", "Feature"), "transcript4");
@@ -583,7 +647,8 @@ public class VCFLoaderTest
     sf = transcriptFeatures.get(2);
     assertEquals(sf.getBegin(), 11);
     assertEquals(sf.getEnd(), 11);
-    assertEquals(sf.getScore(), 0.7f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.7f, DELTA);
     assertEquals(sf.getValue("alleles"), "A,G");
     assertEquals(map.size(), 9);
     assertEquals(sf.getValueAsString("CSQ", "Feature"), "transcript4");
@@ -591,9 +656,64 @@ public class VCFLoaderTest
     sf = transcriptFeatures.get(3);
     assertEquals(sf.getBegin(), 11);
     assertEquals(sf.getEnd(), 11);
-    assertEquals(sf.getScore(), 0.6f, DELTA);
+    assertEquals(sf.getScore(), 0f);
+    assertEquals(Float.parseFloat((String) sf.getValue("AF")), 0.6f, DELTA);
     assertEquals(sf.getValue("alleles"), "A,AC");
     assertEquals(map.size(), 9);
     assertEquals(sf.getValueAsString("CSQ", "Feature"), "transcript4");
   }
-}
+
+  /**
+   * A test that demonstrates loading a contig sequence from an indexed sequence
+   * database which is the reference for a VCF file
+   * 
+   * @throws IOException
+   */
+  @Test(groups = "Functional")
+  public void testLoadVCFContig() throws IOException
+  {
+    VCFLoader loader = new VCFLoader(
+            "test/jalview/io/vcf/testVcf2.vcf");
+
+    SequenceI seq = loader.loadVCFContig("contig123");
+    assertEquals(seq.getLength(), 15);
+    assertEquals(seq.getSequenceAsString(), "AAAAACCCCCGGGGG");
+    List<SequenceFeature> features = seq.getSequenceFeatures();
+    SequenceFeatures.sortFeatures(features, true);
+    assertEquals(features.size(), 2);
+    SequenceFeature sf = features.get(0);
+    assertEquals(sf.getBegin(), 8);
+    assertEquals(sf.getEnd(), 8);
+    assertEquals(sf.getDescription(), "C,A");
+    sf = features.get(1);
+    assertEquals(sf.getBegin(), 12);
+    assertEquals(sf.getEnd(), 12);
+    assertEquals(sf.getDescription(), "G,T");
+
+    seq = loader.loadVCFContig("contig789");
+    assertEquals(seq.getLength(), 25);
+    assertEquals(seq.getSequenceAsString(), "GGGGGTTTTTAAAAACCCCCGGGGG");
+    features = seq.getSequenceFeatures();
+    SequenceFeatures.sortFeatures(features, true);
+    assertEquals(features.size(), 2);
+    sf = features.get(0);
+    assertEquals(sf.getBegin(), 2);
+    assertEquals(sf.getEnd(), 2);
+    assertEquals(sf.getDescription(), "G,T");
+    sf = features.get(1);
+    assertEquals(sf.getBegin(), 21);
+    assertEquals(sf.getEnd(), 21);
+    assertEquals(sf.getDescription(), "G,A");
+
+    seq = loader.loadVCFContig("contig456");
+    assertEquals(seq.getLength(), 20);
+    assertEquals(seq.getSequenceAsString(), "CCCCCGGGGGTTTTTAAAAA");
+    features = seq.getSequenceFeatures();
+    SequenceFeatures.sortFeatures(features, true);
+    assertEquals(features.size(), 1);
+    sf = features.get(0);
+    assertEquals(sf.getBegin(), 15);
+    assertEquals(sf.getEnd(), 15);
+    assertEquals(sf.getDescription(), "T,C");
+  }
+}
\ No newline at end of file