]> git.donarmstrong.com Git - bamtools.git/blob - src/api/BamMultiReader.cpp
Major update to BamTools version 1.0
[bamtools.git] / src / api / BamMultiReader.cpp
1 // ***************************************************************************
2 // BamMultiReader.cpp (c) 2010 Erik Garrison, Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // All rights reserved.
5 // ---------------------------------------------------------------------------
6 // Last modified: 15 March 2011 (DB)
7 // ---------------------------------------------------------------------------
8 // Convenience class for reading multiple BAM files.
9 //
10 // This functionality allows applications to work on very large sets of files
11 // without requiring intermediate merge, sort, and index steps for each file
12 // subset.  It also improves the performance of our merge system as it
13 // precludes the need to sort merged files.
14 // ***************************************************************************
15
16 #include <api/BamMultiReader.h>
17 #include <api/internal/BamMultiReader_p.h>
18 using namespace BamTools;
19
20 #include <string>
21 #include <vector>
22 using namespace std;
23
24 /*! \class BamTools::BamReader
25     \brief Convenience class for reading multiple BAM files.
26 */
27
28 /*! \fn BamMultiReader::BamMultiReader(void)
29     \brief constructor
30 */
31 BamMultiReader::BamMultiReader(void)
32     : d(new Internal::BamMultiReaderPrivate)
33 { }
34
35 /*! \fn BamMultiReader::~BamMultiReader(void)
36     \brief destructor
37 */
38 BamMultiReader::~BamMultiReader(void) {
39     delete d;
40     d = 0;
41 }
42
43 /*! \fn void BamMultiReader::Close(void)
44     \brief Closes all open BAM files.
45
46     Also clears out all header and reference data.
47
48     \sa CloseFile(), IsOpen(), Open(), BamReader::Close()
49 */
50 void BamMultiReader::Close(void) {
51     d->Close();
52 }
53
54 /*! \fn void BamMultiReader::CloseFile(const std::string& filename)
55     \brief Closes requested BAM file.
56
57     Leaves any other file(s) open, along with header and reference data.
58
59     \sa Close(), IsOpen(), Open(), BamReader::Close()
60 */
61 void BamMultiReader::CloseFile(const std::string& filename) {
62     d->CloseFile(filename);
63 }
64
65 /*! \fn bool BamMultiReader::CreateIndexes(const BamIndex::IndexType& type)
66     \brief Creates index files for the current BAM files.
67
68     \param type file format to create, see BamIndex::IndexType for available formats
69     \return \c true if index files created OK
70     \sa LocateIndexes(), OpenIndexes(), BamReader::CreateIndex()
71 */
72 bool BamMultiReader::CreateIndexes(const BamIndex::IndexType& type) {
73     return d->CreateIndexes(type);
74 }
75
76 /*! \fn const std::vector<std::string> BamMultiReader::Filenames(void) const
77     \brief Returns list of filenames for all open BAM files.
78
79     Retrieved filenames will contain whatever was passed via Open().
80     If you need full directory paths here, be sure to include them
81     when you open the BAM files.
82
83     \returns names of open BAM files. If no files are open, returns an empty vector.
84     \sa IsOpen(), BamReader::GetFilename()
85 */
86 const std::vector<std::string> BamMultiReader::Filenames(void) const {
87     return d->Filenames();
88 }
89
90 /*! \fn SamHeader BamMultiReader::GetHeader(void) const
91     \brief Returns unified SAM-format header for all files
92
93     N.B. - Modifying the retrieved text does NOT affect the current
94     BAM files. Thesse file have been opened in a read-only mode. However,
95     your modified header text can be used in conjunction with BamWriter
96     to generate a new BAM file with the appropriate header information.
97
98     \returns header data wrapped in SamHeader object
99     \sa GetHeaderText(), BamReader::GetHeader()
100 */
101 SamHeader BamMultiReader::GetHeader(void) const {
102     return d->GetHeader();
103 }
104
105 /*! \fn std::string BamMultiReader::GetHeaderText(void) const
106     \brief Returns unified SAM-format header text for all files
107
108     N.B. - Modifying the retrieved text does NOT affect the current
109     BAM files. Thesse file have been opened in a read-only mode. However,
110     your modified header text can be used in conjunction with BamWriter
111     to generate a new BAM file with the appropriate header information.
112
113     \returns SAM-formatted header text
114     \sa GetHeader(), BamReader::GetHeaderText()
115 */
116 std::string BamMultiReader::GetHeaderText(void) const {
117     return d->GetHeaderText();
118 }
119
120 /*! \fn bool BamMultiReader::GetNextAlignment(BamAlignment& alignment)
121     \brief Retrieves next available alignment.
122
123     Equivalent to BamReader::GetNextAlignment() with respect to what is a valid
124     overlapping alignment and what data gets populated.
125
126     This method takes care of determining which alignment actually is 'next'
127     across multiple files, depending on current SortOrder.
128
129     \param alignment destination for alignment record data
130     \returns \c true if a valid alignment was found
131     \sa GetNextAlignmentCore(), SetRegion(), SetSortOrder(), BamReader::GetNextAlignment()
132 */
133 bool BamMultiReader::GetNextAlignment(BamAlignment& nextAlignment) {
134     return d->GetNextAlignment(nextAlignment);
135 }
136
137 /*! \fn bool BamMultiReader::GetNextAlignmentCore(BamAlignment& alignment)
138     \brief Retrieves next available alignment.
139
140     Equivalent to BamReader::GetNextAlignmentCore() with respect to what is a valid
141     overlapping alignment and what data gets populated.
142
143     This method takes care of determining which alignment actually is 'next'
144     across multiple files, depending on current SortOrder.
145
146     \param alignment destination for alignment record data
147     \returns \c true if a valid alignment was found
148     \sa GetNextAlignment(), SetRegion(), SetSortOrder(), BamReader::GetNextAlignmentCore()
149 */
150 bool BamMultiReader::GetNextAlignmentCore(BamAlignment& nextAlignment) {
151     return d->GetNextAlignmentCore(nextAlignment);
152 }
153
154 /*! \fn int BamMultiReader::GetReferenceCount(void) const
155     \brief Returns number of reference sequences.
156     \sa BamReader::GetReferenceCount()
157 */
158 int BamMultiReader::GetReferenceCount(void) const {
159     return d->GetReferenceCount();
160 }
161
162 /*! \fn const RefVector& BamMultiReader::GetReferenceData(void) const
163     \brief Returns all reference sequence entries.
164     \sa RefData, BamReader::GetReferenceData()
165 */
166 const BamTools::RefVector BamMultiReader::GetReferenceData(void) const {
167     return d->GetReferenceData();
168 }
169
170 /*! \fn int BamMultiReader::GetReferenceID(const std::string& refName) const
171     \brief Returns the ID of the reference with this name.
172
173     If \a refName is not found, returns -1.
174
175     \sa BamReader::GetReferenceID()
176 */
177 int BamMultiReader::GetReferenceID(const std::string& refName) const {
178     return d->GetReferenceID(refName);
179 }
180
181 /*! \fn bool BamMultiReader::HasIndexes(void) const
182     \brief Returns \c true if all BAM files have index data available.
183     \sa BamReader::HasIndex()
184 */
185 bool BamMultiReader::HasIndexes(void) const {
186     return d->HasIndexes();
187 }
188
189 /*! \fn bool BamMultiReader::HasOpenReaders(void) const
190     \brief Returns \c true if there are any open BAM files.
191 */
192 bool BamMultiReader::HasOpenReaders(void) const {
193     return d->HasOpenReaders();
194 }
195
196 /*! \fn bool BamMultiReader::IsIndexLoaded(void) const
197     \brief Returns \c true if all BAM files have index data available.
198
199     \deprecated Instead use HasIndexes()
200     \cond
201     See explanation in BamReader.cpp for more details on the deprecation decision.
202     \endcond
203 */
204
205 bool BamMultiReader::IsIndexLoaded(void) const {
206     return d->HasIndexes();
207 }
208
209 /*! \fn bool BamMultiReader::Jump(int refID, int position)
210     \brief Performs a random-access jump within current BAM files.
211
212     This is a convenience method, equivalent to calling SetRegion()
213     with only a left boundary specified.
214
215     \returns \c true if jump was successful
216     \sa HasIndex(), BamReader::Jump()
217 */
218
219 bool BamMultiReader::Jump(int refID, int position) {
220     return d->Jump(refID, position);
221 }
222
223 /*! \fn bool BamMultiReader::LocateIndexes(const BamIndex::IndexType& preferredType)
224     \brief Looks for index files that match current BAM files.
225
226     Use this function when you need index files, and perhaps have a
227     preferred index format, but do not depend heavily on which indexes
228     actually get loaded at runtime.
229
230     For each BAM file, this function will defer to your \a preferredType
231     whenever possible. However, if an index file of \a preferredType can
232     not be found, then it will look for any other index file that matches
233     that BAM file.
234
235     An example case would look this:
236     \code
237
238         BamMultiReader reader;
239         // do setup
240
241         // ensure that all files have an index
242         if ( !reader.LocateIndexes() )      // opens any existing index files that match our BAM files
243             reader.CreateIndexes();         // creates index files for BAM files that still lack one
244
245         // do interesting stuff
246         // ...
247
248     \endcode
249
250     If you want precise control over which index files are loaded, use OpenIndexes()
251     with the desired index filenames. If that function returns false, you can use
252     CreateIndexes() to then build index files of the exact requested format.
253
254     \param preferredType desired index file format, see BamIndex::IndexType for available formats
255     \returns \c true if index files could be found for \b ALL open BAM files
256     \sa BamReader::LocateIndex()
257 */
258 bool BamMultiReader::LocateIndexes(const BamIndex::IndexType& preferredType) {
259     return d->LocateIndexes(preferredType);
260 }
261
262 /*! \fn bool BamMultiReader::Open(const std::vector<std::string>& filenames)
263     \brief Opens BAM files.
264
265     N.B. - Opening BAM files will invalidate any current region set on the multireader.
266            All file pointers will be returned to the beginning of the alignment data.
267            Follow this with Jump() or SetRegion() to establish a region of interest.
268
269     \param filenames list of BAM filenames to open
270     \returns \c true if BAM files were opened successfully
271     \sa Close(), HasOpenReaders(), OpenFile(), OpenIndexes(), BamReader::Open()
272 */
273 bool BamMultiReader::Open(const std::vector<std::string>& filenames) {
274     return d->Open(filenames);
275 }
276
277 /*! \fn bool BamMultiReader::OpenFile(const std::string& filename)
278     \brief Opens a single BAM file.
279
280     Adds another BAM file to multireader "on-the-fly".
281
282     N.B. - Opening a BAM file invalidates any current region set on the multireader.
283            All file pointers will be returned to the beginning of the alignment data.
284            Follow this with Jump() or SetRegion() to establish a region of interest.
285
286     \param filename BAM filename to open
287     \returns \c true if BAM file was opened successfully
288     \sa Close(), HasOpenReaders(), Open(), OpenIndexes(), BamReader::Open()
289 */
290 bool BamMultiReader::OpenFile(const std::string& filename) {
291     return d->OpenFile(filename);
292 }
293
294 /*! \fn bool BamMultiReader::OpenIndexes(const std::vector<std::string>& indexFilenames)
295     \brief Opens index files for current BAM files.
296
297     N.B. - Currently assumes that index filenames match the order (and number) of
298     BAM files passed to Open().
299
300     \param indexFilenames list of BAM index file names
301     \returns \c true if BAM index file was opened & data loaded successfully
302     \sa LocateIndex(), Open(), SetIndex(), BamReader::OpenIndex()
303 */
304 bool BamMultiReader::OpenIndexes(const std::vector<std::string>& indexFilenames) {
305     return d->OpenIndexes(indexFilenames);
306 }
307
308 /*! \fn void BamMultiReader::PrintFilenames(void) const
309     \brief Convenience method for printing filenames to stdout.
310     \deprecated Doesn't really belong as an API function. Clients should
311                 determine how the data is reported.
312     \sa Filenames(), BamReader::GetFilename()
313 */
314 void BamMultiReader::PrintFilenames(void) const {
315     d->PrintFilenames();
316 }
317
318 /*! \fn bool BamMultiReader::Rewind(void)
319     \brief Returns the internal file pointers to the beginning of alignment records.
320
321     Useful for performing multiple sequential passes through BAM files.
322     Calling this function clears any prior region that may have been set.
323
324     \returns \c true if rewind operation was successful
325     \sa Jump(), SetRegion(), BamReader::Rewind()
326 */
327 bool BamMultiReader::Rewind(void) {
328     return d->Rewind();
329 }
330
331 /*! \fn void BamMultiReader::SetIndexCacheMode(const BamIndex::IndexCacheMode& mode)
332     \brief Changes the caching behavior of the index data.
333
334     Default mode is BamIndex::LimitedIndexCaching.
335
336     \param mode desired cache mode for index, see BamIndex::IndexCacheMode for
337                 description of the available cache modes
338     \sa HasIndex(), BamReader::SetIndexCacheMode()
339 */
340 void BamMultiReader::SetIndexCacheMode(const BamIndex::IndexCacheMode& mode) {
341     d->SetIndexCacheMode(mode);
342 }
343
344 /*! \fn bool BamMultiReader::SetRegion(const BamRegion& region)
345     \brief Sets a target region of interest
346
347     Equivalent to calling BamReader::SetRegion() on all open BAM files.
348
349     \param region desired region-of-interest to activate
350     \returns \c true if ALL readers set the region successfully
351     \sa HasIndexes(), Jump(), BamReader::SetRegion()
352 */
353 bool BamMultiReader::SetRegion(const BamRegion& region) {
354     return d->SetRegion(region);
355 }
356
357 /*! \fn bool BamMultiReader::SetRegion(const int& leftRefID,
358                                        const int& leftPosition,
359                                        const int& rightRefID,
360                                        const int& rightPosition)
361     \brief Sets a target region of interest
362
363     This is an overloaded function.
364
365     Equivalent to calling BamReader::SetRegion() on all open BAM files.
366
367     \param leftRefID     referenceID of region's left boundary
368     \param leftPosition  position of region's left boundary
369     \param rightRefID    reference ID of region's right boundary
370     \param rightPosition position of region's right boundary
371
372     \returns \c true if ALL readers set the region successfully
373     \sa HasIndexes(), Jump(), BamReader::SetRegion()
374 */
375 bool BamMultiReader::SetRegion(const int& leftRefID,
376                                const int& leftPosition,
377                                const int& rightRefID,
378                                const int& rightPosition)
379 {
380     BamRegion region(leftRefID, leftPosition, rightRefID, rightPosition);
381     return d->SetRegion(region);
382 }
383
384 /*! \fn void BamMultiReader::SetSortOrder(const SortOrder& order)
385     \brief Sets the expected sorting order for reading across multiple BAM files.
386
387     Default is BamMultiReader::SortedByPosition.
388
389     The SortOrder determines how the reader determines which alignment is "next"
390     from among its open readers.
391
392     \param order expected sort order
393 */
394 void BamMultiReader::SetSortOrder(const SortOrder& order) {
395     d->SetSortOrder(order);
396 }