source: trunk/yat/omic/BamFile.h @ 3166

Last change on this file since 3166 was 3166, checked in by Peter, 8 years ago

throw OutBamFile::error when OutBamFile::write fails. closes #778

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.2 KB
Line 
1#ifndef theplu_yat_omic_bam_file
2#define theplu_yat_omic_bam_file
3
4// $Id: BamFile.h 3166 2014-01-17 02:23:05Z peter $
5
6/*
7  Copyright (C) 2012, 2013, 2014 Peter Johansson
8
9  This file is part of the yat library, http://dev.thep.lu.se/yat
10
11  The yat library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU General Public License as
13  published by the Free Software Foundation; either version 3 of the
14  License, or (at your option) any later version.
15
16  The yat library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20
21  You should have received a copy of the GNU General Public License
22  along with this program. If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#include "BamHeader.h"
26#include "BamRead.h"
27#include "config_bam.h"
28
29#include "yat/utility/Exception.h"
30#include "yat/utility/yat_assert.h"
31
32#include YAT_SAM_HEADER
33
34#include <boost/utility.hpp>
35
36#include <cstdio>
37#include <sstream>
38#include <stdexcept>
39#include <string>
40
41namespace theplu {
42namespace yat {
43namespace omic {
44
45  /**
46     Base class for bam files
47
48     \since New in yat 0.10
49   */
50  template<typename Derived>
51  class BamFile : boost::noncopyable
52  {
53    typedef Derived derived_type;
54  public:
55    /**
56       Default Constructor
57     */
58    BamFile(void);
59
60    /**
61       \brief Destructor
62
63       Closes file if it is open.
64     */
65    virtual ~BamFile(void);
66
67    /**
68       \brief close file
69     */
70    void close(void);
71
72    /**
73       \return \c true iff open
74     */
75    bool is_open(void) const;
76  protected:
77    /**
78       open a bam file named \a fn with mode \a mode
79
80       \see samopen
81     */
82    void open_base(const std::string& fn, const std::string& mode,
83                   const void* aux);
84    /**
85       bam file handler
86     */
87    samfile_t* sf_;
88
89    /**
90       \brief filename of bam file
91
92       The filename is set in open_base().
93     */
94    const std::string& filename(void) const { return filename_; }
95  private:
96    std::string filename_;
97  };
98
99
100  /**
101     This class supports reading from a bam file.
102
103     \since New in yat 0.10
104   */
105  class InBamFile : public BamFile<InBamFile>
106  {
107    typedef BamFile<InBamFile> super_t;
108  public:
109    /**
110       \brief Default constructor
111     */
112    InBamFile(void);
113
114    /**
115       Create an input file
116
117       \param fn string specifying the filename
118
119       \see open(const std::string&)
120     */
121    explicit InBamFile(const std::string& fn);
122
123    /**
124       \brief destructor
125     */
126    virtual ~InBamFile(void);
127
128    /**
129       \return header
130     */
131    const BamHeader& header(void) const;
132
133    /**
134       \return index associated with BamFile
135
136       First time this function is called an index file is loaded from
137       disk. If bam file is named 'foo.bam', the index file should be
138       named 'foo.bam.bai'. If no such file exists or this bam file
139       reads from stdin, this function throws.
140     */
141    const bam_index_t* index(void) const;
142
143    /**
144       \brief Open an input bam file.
145
146       Open a bam file named \a fn. If \a fn is "-", \c stdin is used.
147
148       \param fn string specifying the filename
149     */
150    void open(const std::string& fn);
151
152    /**
153       \brief read the next BamRead
154
155       \return true on success
156     */
157    bool read(BamRead& read);
158
159    /**
160       \brief read the next BamRead
161
162       \return true on success
163     */
164    bool read(BamRead& read, bam_iter_t iter);
165  private:
166    BamHeader header_;
167    mutable bam_index_t* index_;
168  };
169
170
171  /**
172     This class supports writing to a bam file.
173
174     \since New in yat 0.10
175   */
176  class OutBamFile : public BamFile<OutBamFile>
177  {
178    typedef BamFile<OutBamFile> super_t;
179  public:
180    /**
181       Create an output bam file
182     */
183    OutBamFile(void);
184
185    /**
186       \brief Create an output bam file.
187
188       Equivalent to default constructor followed by a call to open(2).
189
190       \see open(const std::string&, const BamHeader&)
191     */
192    OutBamFile(const std::string&, const BamHeader& header);
193
194    /**
195       \brief Create an output bam file.
196
197       Equivalent to default constructor followed by a call to open(3).
198
199       \see open(const std::string&, const BamHeader&, unsigned int)
200
201       \since yat 0.12
202     */
203    OutBamFile(const std::string&, const BamHeader& header,
204               unsigned int compression);
205
206    /**
207       \brief Open an output bam file.
208
209       Opens an output bam file and writes the header contained in \a
210       hdr. If \a fn is "-", \c stdout is used.
211
212       \param fn string specifying the filename
213       \param hdr header
214     */
215    void open(const std::string& fn, const BamHeader& hdr);
216
217    /**
218       \brief Open an output bam file.
219
220       Opens an output bam file and writes the header contained in \a
221       hdr. If \a fn is "-", \c stdout is used.
222
223       \param fn string specifying the filename
224       \param hdr header
225       \param compression a number [0,9] indicating level of
226       compression. 9 gives highest compression and 0 indicates no
227       compression (suitable for piping between applications)
228
229       \since yat 0.12
230     */
231    void open(const std::string& fn, const BamHeader& hdr,
232              unsigned int compression);
233
234    /**
235       \brief write a read to output file
236
237       \throw OutBamFile::error if write failed
238
239       \since yat 0.12
240     */
241    void write(const BamRead& read);
242
243    /**
244       \brief Error thrown from OutBamFile::write(const BamRead&) at failure
245     */
246    class error : public utility::IO_error
247    {
248    public:
249      /// \brief Constructor
250      error(const BamRead&);
251      /// \brief Destructor
252      // has to be throw() since base class destructor is
253      virtual ~error(void) throw();
254      /**
255         \return bam read that failed
256       */
257      const BamRead& read(void) const;
258    private:
259      BamRead read_;
260    }; // end of class error
261
262  private:
263  };
264
265
266  // template implementations
267  template<class Derived>
268  BamFile<Derived>::BamFile(void)
269  : sf_(NULL) {}
270
271
272  template<class Derived>
273  BamFile<Derived>::~BamFile(void)
274  {
275    close();
276  }
277
278
279  template<class Derived>
280  void BamFile<Derived>::close(void)
281  {
282    samclose(sf_);
283    sf_ = NULL;
284  }
285
286
287  template<class Derived>
288  bool BamFile<Derived>::is_open(void) const
289  {
290    return sf_;
291  }
292
293
294  template<class Derived>
295  void BamFile<Derived>::open_base(const std::string& fn,
296                                   const std::string& mode,
297                                   const void* aux)
298  {
299    filename_ = fn;
300    YAT_ASSERT(!sf_);
301    sf_ = samopen(fn.c_str(), mode.c_str(), aux);
302    if (!sf_) {
303      std::ostringstream ss;
304      ss << "failed open '" << fn << "'";
305      throw utility::runtime_error(ss.str());
306    }
307  }
308
309}}}
310#endif
Note: See TracBrowser for help on using the repository browser.