]> git.donarmstrong.com Git - bamtools.git/blob - src/api/BamIndex.h
9da858fe025f5922468111e8a5afa3729e64d84a
[bamtools.git] / src / api / BamIndex.h
1 // ***************************************************************************
2 // BamIndex.h (c) 2009 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // All rights reserved.
5 // ---------------------------------------------------------------------------
6 // Last modified: 8 October 2010 (DB)
7 // ---------------------------------------------------------------------------
8 // Provides index functionality - both for the standardized BAM index format
9 // (".bai") as well as a BamTools-specific (nonstandard) index format (".bti").
10 // ***************************************************************************
11
12 #ifndef BAM_INDEX_H
13 #define BAM_INDEX_H
14
15 #include <iostream>
16 #include <string>
17 #include <vector>
18 #include "BamAlignment.h"
19
20 namespace BamTools {
21
22 class BamReader;
23 class BgzfData;
24   
25 // --------------------------------------------------  
26 // BamIndex base class
27 class BamIndex {
28
29     // ctor & dtor
30     public:
31         BamIndex(BamTools::BgzfData* bgzf, BamTools::BamReader* reader, bool isBigEndian);
32         virtual ~BamIndex(void) { }
33         
34     // index interface
35     public:
36         // creates index data (in-memory) from current reader data
37         virtual bool Build(void) =0;
38         // returns supported file extension
39         virtual const std::string Extension(void) const =0;
40         // attempts to use index to jump to region; returns success/fail
41         // a "successful" jump indicates no error, but not whether this region has data
42         //   * thus, the method sets a flag to indicate whether there are alignments 
43         //     available after the jump position
44         virtual bool Jump(const BamTools::BamRegion& region, bool* hasAlignmentsInRegion) =0;
45         // returns whether reference has alignments or no
46         virtual bool HasAlignments(const int& referenceID) const =0;
47         // loads existing data from file into memory
48         virtual bool Load(const std::string& filename)  =0;
49         // writes in-memory index data out to file 
50         // N.B. - (this is the original BAM filename, method will modify it to use applicable extension)
51         virtual bool Write(const std::string& bamFilename) =0;
52         
53     // factory methods for returning proper BamIndex-derived type based on available index files
54     public:
55       
56         // returns index based on BAM filename 'stub'
57         // checks first for preferred type, returns that type if found
58         // (if not found, attmempts to load other type(s), returns 0 if NONE found)
59         //
60         // ** default preferred type is BamToolsIndex ** use this anytime it exists
61         enum PreferredIndexType { BAMTOOLS = 0, STANDARD };
62         static BamIndex* FromBamFilename(const std::string& bamFilename, 
63                                          BamTools::BgzfData* bgzf, 
64                                          BamTools::BamReader* reader, 
65                                          bool isBigEndian, 
66                                          const BamIndex::PreferredIndexType& type = BamIndex::BAMTOOLS);
67         
68         // returns index based on explicitly named index file (or 0 if not found)
69         static BamIndex* FromIndexFilename(const std::string& indexFilename, 
70                                            BamTools::BgzfData* bgzf, 
71                                            BamTools::BamReader* reader, 
72                                            bool isBigEndian);
73
74     // data members
75     protected:
76         BamTools::BgzfData*  m_BGZF;
77         BamTools::BamReader* m_reader;
78         BamTools::RefVector  m_references;
79         bool m_isBigEndian;
80 };
81
82 // --------------------------------------------------
83 // BamStandardIndex class
84 // 
85 // implements standardized (per SAM/BAM spec) index file ops
86 class BamStandardIndex : public BamIndex {
87
88   
89     // ctor & dtor
90     public:
91         BamStandardIndex(BamTools::BgzfData*  bgzf, 
92                         BamTools::BamReader* reader,
93                         bool isBigEndian);
94         ~BamStandardIndex(void);
95         
96     // interface (implements BamIndex virtual methods)
97     public:
98         // creates index data (in-memory) from current reader data
99         bool Build(void);
100         // returns supported file extension
101         const std::string Extension(void) const { return std::string(".bai"); }
102         // returns whether reference has alignments or no
103         bool HasAlignments(const int& referenceID) const;
104         // attempts to use index to jump to region; returns success/fail
105         // a "successful" jump indicates no error, but not whether this region has data
106         //   * thus, the method sets a flag to indicate whether there are alignments 
107         //     available after the jump position
108         bool Jump(const BamTools::BamRegion& region, bool* hasAlignmentsInRegion);
109          // loads existing data from file into memory
110         bool Load(const std::string& filename);
111         // writes in-memory index data out to file 
112         // N.B. - (this is the original BAM filename, method will modify it to use applicable extension)
113         bool Write(const std::string& bamFilename);
114       
115     // internal implementation
116     private:
117         struct BamStandardIndexPrivate;
118         BamStandardIndexPrivate* d;
119 };
120
121 // --------------------------------------------------
122 // BamToolsIndex class
123 //
124 // implements BamTools-specific index file ops
125 class BamToolsIndex : public BamIndex {
126
127     // ctor & dtor
128     public:
129         BamToolsIndex(BamTools::BgzfData*  bgzf, 
130                       BamTools::BamReader* reader,
131                       bool isBigEndian);
132         ~BamToolsIndex(void);
133         
134     // interface (implements BamIndex virtual methods)
135     public:
136         // creates index data (in-memory) from current reader data
137         bool Build(void);
138         // returns supported file extension
139         const std::string Extension(void) const { return std::string(".bti"); }
140         // returns whether reference has alignments or no
141         bool HasAlignments(const int& referenceID) const;
142         // attempts to use index to jump to region; returns success/fail
143         // a "successful" jump indicates no error, but not whether this region has data
144         //   * thus, the method sets a flag to indicate whether there are alignments 
145         //     available after the jump position
146         bool Jump(const BamTools::BamRegion& region, bool* hasAlignmentsInRegion);
147          // loads existing data from file into memory
148         bool Load(const std::string& filename);
149         // writes in-memory index data out to file 
150         // N.B. - (this is the original BAM filename, method will modify it to use applicable extension)
151         bool Write(const std::string& bamFilename);
152     
153     // internal implementation
154     private:
155         struct BamToolsIndexPrivate;
156         BamToolsIndexPrivate* d;
157 };
158
159 // --------------------------------------------------
160 // BamIndex factory methods
161 //
162 // return proper BamIndex-derived type based on available index files
163
164 inline
165 BamIndex* BamIndex::FromBamFilename(const std::string& bamFilename, 
166                                     BamTools::BgzfData* bgzf, 
167                                     BamTools::BamReader* reader, 
168                                     bool isBigEndian, 
169                                     const BamIndex::PreferredIndexType& type)
170 {
171     // ---------------------------------------------------
172     // attempt to load preferred type first
173     
174     const std::string bamtoolsIndexFilename = bamFilename + ".bti";
175     const bool bamtoolsIndexExists = BamTools::FileExists(bamtoolsIndexFilename);
176     if ( (type == BamIndex::BAMTOOLS) && bamtoolsIndexExists )
177         return new BamToolsIndex(bgzf, reader, isBigEndian);
178
179     const std::string standardIndexFilename = bamFilename + ".bai";
180     const bool standardIndexExists = BamTools::FileExists(standardIndexFilename);
181     if ( (type == BamIndex::STANDARD) && standardIndexExists ) 
182         return new BamStandardIndex(bgzf, reader, isBigEndian);
183     
184     // ----------------------------------------------------
185     // preferred type could not be found, try other (non-preferred) types
186     // if none found, return 0
187     
188     if ( bamtoolsIndexExists ) return new BamToolsIndex(bgzf, reader, isBigEndian);
189     if ( standardIndexExists ) return new BamStandardIndex(bgzf, reader, isBigEndian);
190     return 0;
191 }
192
193 inline
194 BamIndex* BamIndex::FromIndexFilename(const std::string& indexFilename,
195                                       BamTools::BgzfData* bgzf, 
196                                       BamTools::BamReader* reader, 
197                                       bool isBigEndian) 
198 {
199     // see if specified file exists
200     const bool indexExists = BamTools::FileExists(indexFilename);
201     if ( !indexExists ) return 0;
202   
203     const std::string bamtoolsIndexExtension(".bti");
204     const std::string standardIndexExtension(".bai");
205   
206     // if has bamtoolsIndexExtension
207     if ( indexFilename.find(bamtoolsIndexExtension) == (indexFilename.length() - bamtoolsIndexExtension.length()) )
208         return new BamToolsIndex(bgzf, reader, isBigEndian);
209     
210      // if has standardIndexExtension
211     if ( indexFilename.find(standardIndexExtension) == (indexFilename.length() - standardIndexExtension.length()) )
212         return new BamStandardIndex(bgzf, reader, isBigEndian);
213
214     // otherwise, unsupported file type
215     return 0;
216 }
217
218 } // namespace BamTools
219
220 #endif // BAM_INDEX_H