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