JAL-1793 wrapper for plain or indexed VCF + simple tests
[jalview.git] / src / jalview / ext / htsjdk / VCFReader.java
1 package jalview.ext.htsjdk;
2
3 import htsjdk.samtools.util.CloseableIterator;
4 import htsjdk.variant.variantcontext.VariantContext;
5 import htsjdk.variant.vcf.VCFFileReader;
6
7 import java.io.Closeable;
8 import java.io.File;
9 import java.io.IOException;
10
11 /**
12  * A thin wrapper for htsjdk classes to read either plain, or compressed, or
13  * compressed and indexed VCF files
14  */
15 public class VCFReader implements Closeable, Iterable<VariantContext>
16 {
17   private static final String GZ = "gz";
18
19   private static final String TBI_EXTENSION = ".tbi";
20
21   private boolean indexed;
22
23   private VCFFileReader reader;
24
25   /**
26    * Constructor given a raw or compressed VCF file or a (tabix) index file
27    * <p>
28    * For now, file type is inferred from its suffix: .gz or .bgz for compressed
29    * data, .tbi for an index file, anything else is assumed to be plain text
30    * VCF.
31    * 
32    * @param f
33    * @throws IOException
34    */
35   public VCFReader(String filePath) throws IOException
36   {
37     if (filePath.endsWith(GZ))
38     {
39       if (new File(filePath + TBI_EXTENSION).exists())
40       {
41         indexed = true;
42       }
43     }
44     else if (filePath.endsWith(TBI_EXTENSION))
45     {
46       indexed = true;
47       filePath = filePath.substring(0, filePath.length() - 4);
48     }
49
50     reader = new VCFFileReader(new File(filePath), indexed);
51   }
52
53   @Override
54   public void close() throws IOException
55   {
56     if (reader != null)
57     {
58       reader.close();
59     }
60   }
61
62   /**
63    * Returns an iterator over VCF variants in the file. The client should call
64    * close() on the iterator when finished with it.
65    */
66   @Override
67   public CloseableIterator<VariantContext> iterator()
68   {
69     return reader == null ? null : reader.iterator();
70   }
71
72   /**
73    * Queries for records overlapping the region specified. Note that this method
74    * requires a VCF file with an associated index. If no index exists a
75    * TribbleException will be thrown.
76    * 
77    * @param chrom
78    *          the chromosome to query
79    * @param start
80    *          query interval start
81    * @param end
82    *          query interval end
83    * @return
84    */
85   public CloseableIterator<VariantContext> query(final String chrom,
86           final int start, final int end)
87   {
88     return reader == null ? null : reader.query(chrom, start, end);
89   }
90 }