]> git.donarmstrong.com Git - bamtools.git/blob - src/api/SamSequenceDictionary.cpp
3249bd4162d846c174a8889546531e62f0a32e47
[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: 20 March 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 discarded.
44
45     \param 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 }
51
52 /*! \fn void SamSequenceDictionary::Add(const std::string& name, const int& length)
53     \brief Adds a sequence to the dictionary.
54
55     This is an overloaded function.
56
57     \param name name of sequence entry to be added
58     \param length length of sequence entry to be added
59     \sa Add()
60 */
61 void SamSequenceDictionary::Add(const std::string& name, const int& length) {
62     Add( SamSequence(name, length) );
63 }
64
65 /*! \fn void SamSequenceDictionary::Add(const std::vector<SamSequence>& sequences)
66     \brief Adds multiple sequences to the dictionary.
67
68     This is an overloaded function.
69
70     \param sequences entries to be added
71     \sa Add()
72 */
73 void SamSequenceDictionary::Add(const std::vector<SamSequence>& sequences) {
74     vector<SamSequence>::const_iterator seqIter = sequences.begin();
75     vector<SamSequence>::const_iterator seqEnd  = sequences.end();
76     for ( ; seqIter!= seqEnd; ++seqIter )
77         Add(*seqIter);
78 }
79
80 /*! \fn void SamSequenceDictionary::Add(const std::map<std::string, int>& sequenceMap)
81     \brief Adds multiple sequences to the dictionary.
82
83     This is an overloaded function.
84
85     \param sequenceMap map of sequence entries (name => length) to be added
86     \sa Add()
87 */
88 void SamSequenceDictionary::Add(const std::map<std::string, int>& sequenceMap) {
89     map<string, int>::const_iterator seqIter = sequenceMap.begin();
90     map<string, int>::const_iterator seqEnd  = sequenceMap.end();
91     for ( ; seqIter != seqEnd; ++seqIter ) {
92         const string& name = (*seqIter).first;
93         const int& length = (*seqIter).second;
94         Add( SamSequence(name, length) );
95     }
96 }
97
98 /*! \fn SamSequenceIterator SamSequenceDictionary::Begin(void)
99     \return an STL iterator pointing to the first sequence
100     \sa ConstBegin(), End()
101 */
102 SamSequenceIterator SamSequenceDictionary::Begin(void) {
103     return m_data.begin();
104 }
105
106 /*! \fn SamSequenceConstIterator SamSequenceDictionary::Begin(void) const
107
108     This is an overloaded function.
109
110     \return a const STL iterator pointing to the first sequence
111     \sa ConstBegin(), End()
112 */
113 SamSequenceConstIterator SamSequenceDictionary::Begin(void) const {
114     return m_data.begin();
115 }
116
117 /*! \fn void SamSequenceDictionary::Clear(void)
118     \brief Clears all sequence entries.
119 */
120 void SamSequenceDictionary::Clear(void) {
121     m_data.clear();
122 }
123
124 /*! \fn SamSequenceConstIterator SamSequenceDictionary::ConstBegin(void) const
125     \return a const STL iterator pointing to the first sequence
126     \sa Begin(), ConstEnd()
127 */
128 SamSequenceConstIterator SamSequenceDictionary::ConstBegin(void) const {
129     return m_data.begin();
130 }
131
132 /*! \fn SamSequenceConstIterator SamSequenceDictionary::ConstEnd(void) const
133     \return a const STL iterator pointing to the imaginary entry after the last sequence
134     \sa End(), ConstBegin()
135 */
136 SamSequenceConstIterator SamSequenceDictionary::ConstEnd(void) const {
137     return m_data.end();
138 }
139
140 /*! \fn bool SamSequenceDictionary::Contains(const std::string& sequenceName) const
141     \brief Returns true if dictionary contains sequence.
142     \param sequenceName search for sequence matching this name
143     \return \c true if dictionary contains a sequence with this name
144 */
145 bool SamSequenceDictionary::Contains(const std::string& sequenceName) const {
146     return ( IndexOf(sequenceName) != (int)m_data.size() );
147 }
148
149 /*! \fn bool SamSequenceDictionary::Contains(const SamSequence& sequence) const
150     \brief Returns true if dictionary contains sequence.
151     \param sequence search for this sequence
152     \return \c true if dictionary contains sequence
153 */
154 bool SamSequenceDictionary::Contains(const SamSequence& sequence) const {
155     return ( IndexOf(sequence) != (int)m_data.size() );
156 }
157
158 /*! \fn SamSequenceIterator SamSequenceDictionary::End(void)
159     \return an STL iterator pointing to the imaginary entry after the last sequence
160     \sa Begin(), ConstEnd()
161 */
162 SamSequenceIterator SamSequenceDictionary::End(void) {
163     return m_data.end();
164 }
165
166 /*! \fn SamSequenceConstIterator SamSequenceDictionary::End(void) const
167
168     This is an overloaded function.
169
170     \return a const STL iterator pointing to the imaginary entry after the last sequence
171     \sa Begin(), ConstEnd()
172 */
173 SamSequenceConstIterator SamSequenceDictionary::End(void) const {
174     return m_data.end();
175 }
176
177 /*! \fn int SamSequenceDictionary::IndexOf(const SamSequence& sequence) const
178     \internal
179
180     Uses operator==(SamSequence, SamSequence)
181
182     \return index of sequence if found.  Otherwise, returns vector::size() (invalid index).
183 */
184 int SamSequenceDictionary::IndexOf(const SamSequence& sequence) const {
185     SamSequenceConstIterator begin = ConstBegin();
186     SamSequenceConstIterator iter  = begin;
187     SamSequenceConstIterator end   = ConstEnd();
188     for ( ; iter != end; ++iter ) {
189         const SamSequence& currentSeq = (*iter);
190         if ( currentSeq == sequence )
191             break;
192     }
193     return distance( begin, iter );
194 }
195
196 /*! \fn int SamSequenceDictionary::IndexOf(const std::string& name) const
197     \internal
198
199     Use comparison of SamSequence::Name to \a name
200
201     \return index of sequence if found.  Otherwise, returns vector::size() (invalid index).
202 */
203 int SamSequenceDictionary::IndexOf(const std::string& name) const {
204     SamSequenceConstIterator begin = ConstBegin();
205     SamSequenceConstIterator iter  = begin;
206     SamSequenceConstIterator end   = ConstEnd();
207     for ( ; iter != end; ++iter ) {
208         const SamSequence& currentSeq = (*iter);
209         if ( currentSeq.Name == name )
210             break;
211     }
212     return distance( begin, iter );
213 }
214
215 /*! \fn bool SamSequenceDictionary::IsEmpty(void) const
216     \brief Returns \c true if dictionary contains no sequences
217     \sa Size()
218 */
219 bool SamSequenceDictionary::IsEmpty(void) const {
220     return m_data.empty();
221 }
222
223 /*! \fn void SamSequenceDictionary::Remove(const SamSequence& sequence)
224     \brief Removes sequence from dictionary, if found.
225     \param sequence sequence to remove
226 */
227 void SamSequenceDictionary::Remove(const SamSequence& sequence) {
228     if ( Contains(sequence) )
229         m_data.erase( m_data.begin() + IndexOf(sequence) );
230 }
231
232 /*! \fn void SamSequenceDictionary::Remove(const std::string& sequenceName)
233     \brief Removes sequence from dictionary, if found.
234
235     \param sequenceName name of sequence to remove
236     \sa Remove()
237 */
238 void SamSequenceDictionary::Remove(const std::string& sequenceName) {
239     if ( Contains(sequenceName) )
240         m_data.erase( m_data.begin() + IndexOf(sequenceName) );
241 }
242
243 /*! \fn void SamSequenceDictionary::Remove(const std::vector<SamSequence>& sequences)
244     \brief Removes multiple sequences from dictionary.
245
246     This is an overloaded function.
247
248     \param sequences sequences to remove
249     \sa Remove()
250 */
251 void SamSequenceDictionary::Remove(const std::vector<SamSequence>& sequences) {
252     vector<SamSequence>::const_iterator rgIter = sequences.begin();
253     vector<SamSequence>::const_iterator rgEnd  = sequences.end();
254     for ( ; rgIter!= rgEnd; ++rgIter )
255         Remove(*rgIter);
256 }
257
258 /*! \fn void SamSequenceDictionary::Remove(const std::vector<std::string>& sequenceNames)
259     \brief Removes multiple sequences from dictionary.
260
261     This is an overloaded function.
262
263     \param sequenceNames names of the sequences to remove
264     \sa Remove()
265 */
266 void SamSequenceDictionary::Remove(const std::vector<std::string>& sequenceNames) {
267     vector<string>::const_iterator rgIter = sequenceNames.begin();
268     vector<string>::const_iterator rgEnd  = sequenceNames.end();
269     for ( ; rgIter!= rgEnd; ++rgIter )
270         Remove(*rgIter);
271 }
272
273 /*! \fn int SamSequenceDictionary::Size(void) const
274     \brief Returns number of sequences in dictionary.
275     \sa IsEmpty()
276 */
277 int SamSequenceDictionary::Size(void) const {
278     return m_data.size();
279 }
280
281 /*! \fn SamSequence& SamSequenceDictionary::operator[](const std::string& sequenceName)
282     \brief Retrieves the modifiable SamSequence that matches \a sequenceName.
283
284     NOTE - If the dictionary contains no sequence matching this name, this function inserts
285     a new one with this name, and returns a reference to it.
286
287     If you want to avoid this insertion behavior, check the result of Contains() before
288     using this operator.
289
290     \param sequenceName name of sequence to retrieve
291     \return a modifiable reference to the SamSequence associated with the name
292 */
293 SamSequence& SamSequenceDictionary::operator[](const std::string& sequenceName) {
294
295     // look up sequence ID
296     int index = IndexOf(sequenceName);
297
298     // if found, return sequence at index
299     if ( index != (int)m_data.size() )
300         return m_data[index];
301
302     // otherwise, append new sequence and return reference
303     else {
304         m_data.push_back( SamSequence(sequenceName, 0) );
305         return m_data.back();
306     }
307 }