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