]> git.donarmstrong.com Git - bamtools.git/blob - src/api/SamSequenceDictionary.cpp
Fixed regression: improper @SQ line ordering in SamHeader output
[bamtools.git] / src / api / SamSequenceDictionary.cpp
1 // ***************************************************************************
2 // SamSequenceDictionary.cpp (c) 2010 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // ---------------------------------------------------------------------------
5 // Last modified: 14 October 2011 (DB)
6 // ---------------------------------------------------------------------------
7 // Provides methods for operating on a collection of SamSequence entries.
8 // *************************************************************************
9
10 #include "api/SamSequenceDictionary.h"
11 using namespace BamTools;
12
13 #include <iostream>
14 using namespace std;
15
16 /*! \class BamTools::SamSequenceDictionary
17     \brief Container of SamSequence entries.
18
19     Provides methods for operating on a collection of SamSequence entries.
20 */
21
22 /*! \fn SamSequenceDictionary::SamSequenceDictionary(void)
23     \brief constructor
24 */
25 SamSequenceDictionary::SamSequenceDictionary(void) { }
26
27 /*! \fn SamSequenceDictionary::SamSequenceDictionary(const SamSequenceDictionary& other)
28     \brief copy constructor
29 */
30 SamSequenceDictionary::SamSequenceDictionary(const SamSequenceDictionary& other)
31     : m_data(other.m_data)
32     , m_lookupData(other.m_lookupData)
33 { }
34
35 /*! \fn SamSequenceDictionary::~SamSequenceDictionary(void)
36     \brief destructor
37 */
38 SamSequenceDictionary::~SamSequenceDictionary(void) { }
39
40 /*! \fn void SamSequenceDictionary::Add(const SamSequence& sequence)
41     \brief Appends a sequence to the dictionary.
42
43     Duplicate entries are silently discarded.
44
45     \param[in] sequence entry to be added
46 */
47 void SamSequenceDictionary::Add(const SamSequence& sequence) {
48     if ( IsEmpty() || !Contains(sequence) ) {
49         m_data.push_back(sequence);
50         m_lookupData[sequence.Name] = sequence;
51     }
52 }
53
54 /*! \fn void SamSequenceDictionary::Add(const std::string& name, const int& length)
55     \brief Appends a sequence to the dictionary.
56
57     This is an overloaded function.
58
59     \param[in] name name of sequence entry to be added
60     \param[in] length length of sequence entry to be added
61     \sa Add()
62 */
63 void SamSequenceDictionary::Add(const std::string& name, const int& length) {
64     Add( SamSequence(name, length) );
65 }
66
67 /*! \fn void SamSequenceDictionary::Add(const SamSequenceDictionary& sequences)
68     \brief Appends another sequence dictionary to this one
69
70     This is an overloaded function.
71
72     \param[in] sequences sequence dictionary to be appended
73     \sa Add()
74 */
75 void SamSequenceDictionary::Add(const SamSequenceDictionary& sequences) {
76     SamSequenceConstIterator seqIter = sequences.ConstBegin();
77     SamSequenceConstIterator seqEnd  = sequences.ConstEnd();
78     for ( ; seqIter != seqEnd; ++seqIter )
79         Add(*seqIter);
80 }
81
82 /*! \fn void SamSequenceDictionary::Add(const std::vector<SamSequence>& sequences)
83     \brief Appends multiple sequences to the dictionary.
84
85     This is an overloaded function.
86
87     \param[in] sequences entries to be added
88     \sa Add()
89 */
90 void SamSequenceDictionary::Add(const std::vector<SamSequence>& sequences) {
91     vector<SamSequence>::const_iterator seqIter = sequences.begin();
92     vector<SamSequence>::const_iterator seqEnd  = sequences.end();
93     for ( ; seqIter!= seqEnd; ++seqIter )
94         Add(*seqIter);
95 }
96
97 /*! \fn void SamSequenceDictionary::Add(const std::map<std::string, int>& sequenceMap)
98     \brief Appends multiple sequences to the dictionary.
99
100     This is an overloaded function.
101
102     \param[in] sequenceMap map of sequence entries (name => length) to be added
103     \sa Add()
104 */
105 void SamSequenceDictionary::Add(const std::map<std::string, int>& sequenceMap) {
106     map<string, int>::const_iterator seqIter = sequenceMap.begin();
107     map<string, int>::const_iterator seqEnd  = sequenceMap.end();
108     for ( ; seqIter != seqEnd; ++seqIter ) {
109         const string& name = (*seqIter).first;
110         const int& length = (*seqIter).second;
111         Add( SamSequence(name, length) );
112     }
113 }
114
115 /*! \fn SamSequenceIterator SamSequenceDictionary::Begin(void)
116     \return an STL iterator pointing to the first sequence
117     \sa ConstBegin(), End()
118 */
119 SamSequenceIterator SamSequenceDictionary::Begin(void) {
120     return m_data.begin();
121 }
122
123 /*! \fn SamSequenceConstIterator SamSequenceDictionary::Begin(void) const
124     \return an STL const_iterator pointing to the first sequence
125
126     This is an overloaded function.
127
128     \sa ConstBegin(), End()
129 */
130 SamSequenceConstIterator SamSequenceDictionary::Begin(void) const {
131     return m_data.begin();
132 }
133
134 /*! \fn void SamSequenceDictionary::Clear(void)
135     \brief Clears all sequence entries.
136 */
137 void SamSequenceDictionary::Clear(void) {
138     m_data.clear();
139     m_lookupData.clear();
140 }
141
142 /*! \fn SamSequenceConstIterator SamSequenceDictionary::ConstBegin(void) const
143     \return an STL const_iterator pointing to the first sequence
144     \sa Begin(), ConstEnd()
145 */
146 SamSequenceConstIterator SamSequenceDictionary::ConstBegin(void) const {
147     return m_data.begin();
148 }
149
150 /*! \fn SamSequenceConstIterator SamSequenceDictionary::ConstEnd(void) const
151     \return an STL const_iterator pointing to the imaginary entry after the last sequence
152     \sa End(), ConstBegin()
153 */
154 SamSequenceConstIterator SamSequenceDictionary::ConstEnd(void) const {
155     return m_data.end();
156 }
157
158 /*! \fn bool SamSequenceDictionary::Contains(const std::string& sequenceName) const
159     \brief Returns true if dictionary contains sequence.
160
161     \param[in] sequenceName search for sequence matching this name
162     \return \c true if dictionary contains a sequence with this name
163 */
164 bool SamSequenceDictionary::Contains(const std::string& sequenceName) const {
165     return ( m_lookupData.find(sequenceName) != m_lookupData.end() );
166 }
167
168 /*! \fn bool SamSequenceDictionary::Contains(const SamSequence& sequence) const
169     \brief Returns true if dictionary contains sequence (matches on name).
170
171     This is an overloaded function.
172
173     \param[in] sequence search for this sequence
174     \return \c true if dictionary contains sequence (matching on name)
175 */
176 bool SamSequenceDictionary::Contains(const SamSequence& sequence) const {
177     return Contains(sequence.Name);
178 }
179
180 /*! \fn SamSequenceIterator SamSequenceDictionary::End(void)
181     \return an STL iterator pointing to the imaginary entry after the last sequence
182     \sa Begin(), ConstEnd()
183 */
184 SamSequenceIterator SamSequenceDictionary::End(void) {
185     return m_data.end();
186 }
187
188 /*! \fn SamSequenceConstIterator SamSequenceDictionary::End(void) const
189     \return an STL const_iterator pointing to the imaginary entry after the last sequence
190
191     This is an overloaded function.
192
193     \sa Begin(), ConstEnd()
194 */
195 SamSequenceConstIterator SamSequenceDictionary::End(void) const {
196     return m_data.end();
197 }
198
199 /*! \fn bool SamSequenceDictionary::IsEmpty(void) const
200     \brief Returns \c true if dictionary contains no sequences
201     \sa Size()
202 */
203 bool SamSequenceDictionary::IsEmpty(void) const {
204     return m_data.empty();
205 }
206
207 /*! \fn void SamSequenceDictionary::Remove(const SamSequence& sequence)
208     \brief Removes sequence from dictionary, if found (matches on name).
209
210     This is an overloaded function.
211
212     \param[in] sequence SamSequence to remove (matching on name)
213 */
214 void SamSequenceDictionary::Remove(const SamSequence& sequence) {
215     Remove(sequence.Name);
216 }
217
218 /*! \fn void SamSequenceDictionary::Remove(const std::string& sequenceName)
219     \brief Removes sequence from dictionary, if found.
220
221     \param[in] sequenceName name of sequence to remove
222     \sa Remove()
223 */
224 void SamSequenceDictionary::Remove(const std::string& sequenceName) {
225
226     SamSequenceIterator seqIter = Begin();
227     SamSequenceIterator seqEnd  = End();
228     for ( size_t i = 0 ; seqIter != seqEnd; ++seqIter, ++i ) {
229         SamSequence& seq = (*seqIter);
230         if( seq.Name == sequenceName ) {
231             m_data.erase( Begin() + i );
232         }
233     }
234
235     m_lookupData.erase(sequenceName);
236 }
237
238 /*! \fn void SamSequenceDictionary::Remove(const std::vector<SamSequence>& sequences)
239     \brief Removes multiple sequences from dictionary.
240
241     This is an overloaded function.
242
243     \param[in] sequences sequences to remove
244     \sa Remove()
245 */
246 void SamSequenceDictionary::Remove(const std::vector<SamSequence>& sequences) {
247     vector<SamSequence>::const_iterator rgIter = sequences.begin();
248     vector<SamSequence>::const_iterator rgEnd  = sequences.end();
249     for ( ; rgIter!= rgEnd; ++rgIter )
250         Remove(*rgIter);
251 }
252
253 /*! \fn void SamSequenceDictionary::Remove(const std::vector<std::string>& sequenceNames)
254     \brief Removes multiple sequences from dictionary.
255
256     This is an overloaded function.
257
258     \param[in] sequenceNames names of the sequences to remove
259     \sa Remove()
260 */
261 void SamSequenceDictionary::Remove(const std::vector<std::string>& sequenceNames) {
262     vector<string>::const_iterator rgIter = sequenceNames.begin();
263     vector<string>::const_iterator rgEnd  = sequenceNames.end();
264     for ( ; rgIter!= rgEnd; ++rgIter )
265         Remove(*rgIter);
266 }
267
268 /*! \fn int SamSequenceDictionary::Size(void) const
269     \brief Returns number of sequences in dictionary.
270     \sa IsEmpty()
271 */
272 int SamSequenceDictionary::Size(void) const {
273     return m_data.size();
274 }
275
276 /*! \fn SamSequence& SamSequenceDictionary::operator[](const std::string& sequenceName)
277     \brief Retrieves the modifiable SamSequence that matches \a sequenceName.
278
279     \note If the dictionary contains no sequence matching this name, this function inserts
280     a new one with this name (length:0), and returns a reference to it. If you want to avoid
281     this insertion behavior, check the result of Contains() before using this operator.
282
283     \param[in] sequenceName name of sequence to retrieve
284     \return a modifiable reference to the SamSequence associated with the name
285 */
286 SamSequence& SamSequenceDictionary::operator[](const std::string& sequenceName) {
287     if ( !Contains(sequenceName) ) {
288         SamSequence seq(sequenceName, 0);
289         m_data.push_back(seq);
290         m_lookupData[sequenceName] = seq;
291     }
292     return m_lookupData[sequenceName];
293 }