]> git.donarmstrong.com Git - bamtools.git/blob - src/api/BamIndex.h
Reimplemented BamToolsIndex for bug fix and performance upgrade. *** NOTE *** This...
[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: 10 September 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 "BamAux.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         virtual bool Jump(const BamTools::BamRegion& region) =0;
42         // returns whether reference has alignments or no
43         virtual bool HasAlignments(const int& referenceID); 
44         // loads existing data from file into memory
45         virtual bool Load(const std::string& filename)  =0;
46         // writes in-memory index data out to file 
47         // N.B. - (this is the original BAM filename, method will modify it to use applicable extension)
48         virtual bool Write(const std::string& bamFilename) =0;
49         
50     // factory methods for returning proper BamIndex-derived type based on available index files
51     public:
52       
53         // returns index based on BAM filename 'stub'
54         // checks first for preferred type, returns that type if found
55         // (if not found, attmempts to load other type(s), returns 0 if NONE found)
56         //
57         // ** default preferred type is BamToolsIndex ** use this anytime it exists
58          enum PreferredIndexType { BAMTOOLS = 0, STANDARD };
59         static BamIndex* FromBamFilename(const std::string& bamFilename, 
60                                          BamTools::BgzfData* bgzf, 
61                                          BamTools::BamReader* reader, 
62                                          bool isBigEndian, 
63                                          const BamIndex::PreferredIndexType& type = BamIndex::BAMTOOLS);
64         
65         // returns index based on explicitly named index file (or 0 if not found)
66         static BamIndex* FromIndexFilename(const std::string& indexFilename, 
67                                            BamTools::BgzfData* bgzf, 
68                                            BamTools::BamReader* reader, 
69                                            bool isBigEndian);
70
71     // data members
72     protected:
73         BamTools::BgzfData*  m_BGZF;
74         BamTools::BamReader* m_reader;
75         BamTools::RefVector  m_references;
76         bool m_isBigEndian;
77 };
78
79 // --------------------------------------------------
80 // BamStandardIndex class
81 // 
82 // implements standardized (per SAM/BAM spec) index file ops
83 class BamStandardIndex : public BamIndex {
84
85   
86     // ctor & dtor
87     public:
88         BamStandardIndex(BamTools::BgzfData*  bgzf, 
89                         BamTools::BamReader* reader,
90                         bool isBigEndian);
91         ~BamStandardIndex(void);
92         
93     // interface (implements BamIndex virtual methods)
94     public:
95         // creates index data (in-memory) from current reader data
96         bool Build(void);
97         // returns supported file extension
98         const std::string Extension(void) const { return std::string(".bai"); }
99         // attempts to use index to jump to region; returns success/fail
100         bool Jump(const BamTools::BamRegion& region);
101          // loads existing data from file into memory
102         bool Load(const std::string& filename);
103         // writes in-memory index data out to file 
104         // N.B. - (this is the original BAM filename, method will modify it to use applicable extension)
105         bool Write(const std::string& bamFilename);
106       
107     // internal implementation
108     private:
109         struct BamStandardIndexPrivate;
110         BamStandardIndexPrivate* d;
111 };
112
113 // --------------------------------------------------
114 // BamToolsIndex class
115 //
116 // implements BamTools-specific index file ops
117 class BamToolsIndex : public BamIndex {
118
119     // ctor & dtor
120     public:
121         BamToolsIndex(BamTools::BgzfData*  bgzf, 
122                       BamTools::BamReader* reader,
123                       bool isBigEndian);
124         ~BamToolsIndex(void);
125         
126     // interface (implements BamIndex virtual methods)
127     public:
128         // creates index data (in-memory) from current reader data
129         bool Build(void);
130         // returns supported file extension
131         const std::string Extension(void) const { return std::string(".bti"); }
132         // attempts to use index to jump to region; returns success/fail
133         bool Jump(const BamTools::BamRegion& region);
134          // loads existing data from file into memory
135         bool Load(const std::string& filename);
136         // writes in-memory index data out to file 
137         // N.B. - (this is the original BAM filename, method will modify it to use applicable extension)
138         bool Write(const std::string& bamFilename);
139     
140     // internal implementation
141     private:
142         struct BamToolsIndexPrivate;
143         BamToolsIndexPrivate* d;
144 };
145
146 // --------------------------------------------------
147 // BamIndex factory methods
148 //
149 // return proper BamIndex-derived type based on available index files
150
151 inline
152 BamIndex* BamIndex::FromBamFilename(const std::string& bamFilename, 
153                                     BamTools::BgzfData* bgzf, 
154                                     BamTools::BamReader* reader, 
155                                     bool isBigEndian, 
156                                     const BamIndex::PreferredIndexType& type)
157 {
158     // ---------------------------------------------------
159     // attempt to load preferred type first
160     
161     const std::string bamtoolsIndexFilename = bamFilename + ".bti";
162     const bool bamtoolsIndexExists = BamTools::FileExists(bamtoolsIndexFilename);
163     if ( (type == BamIndex::BAMTOOLS) && bamtoolsIndexExists )
164         return new BamToolsIndex(bgzf, reader, isBigEndian);
165
166     const std::string standardIndexFilename = bamFilename + ".bai";
167     const bool standardIndexExists = BamTools::FileExists(standardIndexFilename);
168     if ( (type == BamIndex::STANDARD) && standardIndexExists ) 
169         return new BamStandardIndex(bgzf, reader, isBigEndian);
170     
171     // ----------------------------------------------------
172     // preferred type could not be found, try other (non-preferred) types
173     // if none found, return 0
174     
175     if ( bamtoolsIndexExists ) return new BamToolsIndex(bgzf, reader, isBigEndian);
176     if ( standardIndexExists ) return new BamStandardIndex(bgzf, reader, isBigEndian);
177     return 0;
178 }
179
180 inline
181 BamIndex* BamIndex::FromIndexFilename(const std::string& indexFilename,
182                                       BamTools::BgzfData* bgzf, 
183                                       BamTools::BamReader* reader, 
184                                       bool isBigEndian) 
185 {
186     // see if specified file exists
187     const bool indexExists = BamTools::FileExists(indexFilename);
188     if ( !indexExists ) return 0;
189   
190     const std::string bamtoolsIndexExtension(".bti");
191     const std::string standardIndexExtension(".bai");
192   
193     // if has bamtoolsIndexExtension
194     if ( indexFilename.find(bamtoolsIndexExtension) == (indexFilename.length() - bamtoolsIndexExtension.length()) )
195         return new BamToolsIndex(bgzf, reader, isBigEndian);
196     
197      // if has standardIndexExtension
198     if ( indexFilename.find(standardIndexExtension) == (indexFilename.length() - standardIndexExtension.length()) )
199         return new BamStandardIndex(bgzf, reader, isBigEndian);
200
201     // otherwise, unsupported file type
202     return 0;
203 }
204
205 } // namespace BamTools
206
207 #endif // BAM_INDEX_H