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