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