1 // ***************************************************************************
2 // SamProgramChain.cpp (c) 2011 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // All rights reserved.
5 // ---------------------------------------------------------------------------
6 // Last modified: 19 April 2011 (DB)
7 // ---------------------------------------------------------------------------
8 // Provides methods for operating on a SamProgram record "chain"
9 // ***************************************************************************
11 #include <api/SamProgramChain.h>
12 using namespace BamTools;
19 /*! \class BamTools::SamProgramChain
20 \brief Sorted container "chain" of SamProgram records.
22 Provides methods for operating on a collection of SamProgram records.
24 N.B. - Underlying container is *NOT* ordered by linkage, but by order of
25 appearance in SamHeader and subsequent Add() calls. Using the current
26 iterators will not allow you to step through the header's program history.
27 Instead use First()/Last() to access oldest/newest records, respectively.
30 /*! \fn SamProgramChain::SamProgramChain(void)
33 SamProgramChain::SamProgramChain(void) { }
35 /*! \fn SamProgramChain::SamProgramChain(const SamProgramChain& other)
36 \brief copy constructor
38 SamProgramChain::SamProgramChain(const SamProgramChain& other)
39 : m_data(other.m_data)
42 /*! \fn SamProgramChain::~SamProgramChain(void)
45 SamProgramChain::~SamProgramChain(void) { }
47 /*! \fn void SamProgramChain::Add(SamProgram& program)
48 \brief Appends a program to program chain.
50 Duplicate entries are silently discarded.
52 N.B. - Underlying container is *NOT* ordered by linkage, but by order of
53 appearance in SamHeader and subsequent Add() calls. Using the current
54 iterators will not allow you to step through the header's program history.
55 Instead use First()/Last() to access oldest/newest records, respectively.
57 \param program entry to be appended
59 void SamProgramChain::Add(SamProgram& program) {
61 // ignore duplicated records
62 if ( Contains(program) )
65 // if other programs already in chain, try to find the "next" record
66 // tries to match another record's PPID with @program's ID
68 program.NextProgramID = NextIdFor(program.ID);
70 // store program record
71 m_data.push_back(program);
74 /*! \fn void SamProgramChain::Add(const std::vector<SamProgram>& programs)
75 \brief Appends a batch of programs to the end of the chain.
77 This is an overloaded function.
79 \param programs batch of program records to append
82 void SamProgramChain::Add(std::vector<SamProgram>& programs) {
83 vector<SamProgram>::iterator pgIter = programs.begin();
84 vector<SamProgram>::iterator pgEnd = programs.end();
85 for ( ; pgIter != pgEnd; ++pgIter )
89 /*! \fn SamProgramIterator SamProgramChain::Begin(void)
90 \return an STL iterator pointing to the first (oldest) program record
91 \sa ConstBegin(), End(), First()
93 SamProgramIterator SamProgramChain::Begin(void) {
94 return m_data.begin();
97 /*! \fn SamProgramConstIterator SamProgramChain::Begin(void) const
98 \return an STL const_iterator pointing to the first (oldest) program record
100 This is an overloaded function.
102 \sa ConstBegin(), End(), First()
104 SamProgramConstIterator SamProgramChain::Begin(void) const {
105 return m_data.begin();
108 /*! \fn void SamProgramChain::Clear(void)
109 \brief Clears all program records.
111 void SamProgramChain::Clear(void) {
115 /*! \fn SamProgramConstIterator SamProgramChain::ConstBegin(void) const
116 \return an STL const_iterator pointing to the first (oldest) program record
117 \sa Begin(), ConstEnd(), First()
119 SamProgramConstIterator SamProgramChain::ConstBegin(void) const {
120 return m_data.begin();
123 /*! \fn SamProgramConstIterator SamProgramChain::ConstEnd(void) const
124 \return an STL const_iterator pointing to the imaginary entry after the last (newest) program record
125 \sa ConstBegin(), End(), Last()
127 SamProgramConstIterator SamProgramChain::ConstEnd(void) const {
131 /*! \fn bool SamProgramChain::Contains(const SamProgram& program) const
132 \brief Returns true if chains has this program record (matching on ID).
134 This is an overloaded function.
136 \param program SamProgram to search for
137 \return \c true if chain contains program (matching on ID)
139 bool SamProgramChain::Contains(const SamProgram& program) const {
140 return Contains(program.ID);
143 /*! \fn bool SamProgramChain::Contains(const std::string& programId) const
144 \brief Returns true if chains has a program record with this ID
145 \param programId search for program matching this ID
146 \return \c true if chain contains a program record with this ID
148 bool SamProgramChain::Contains(const std::string& programId) const {
149 return ( IndexOf(programId) != (int)m_data.size() );
152 /*! \fn SamProgramIterator SamProgramChain::End(void)
153 \return an STL iterator pointing to the imaginary entry after the last (newest) program record
154 \sa Begin(), ConstEnd(), Last()
156 SamProgramIterator SamProgramChain::End(void) {
160 /*! \fn SamProgramConstIterator SamProgramChain::End(void) const
161 \return an STL const_iterator pointing to the imaginary entry after the last (newest) program record
163 This is an overloaded function.
165 \sa Begin(), ConstEnd(), Last()
167 SamProgramConstIterator SamProgramChain::End(void) const {
171 /*! \fn SamProgram& SamProgramChain::First(void)
172 \brief Fetches first (oldest) record in the chain.
174 N.B. - This function will fail if the chain is empty. If this is possible,
175 check the result of IsEmpty() before calling this function.
177 \return a modifiable reference to the first (oldest) program entry
180 SamProgram& SamProgramChain::First(void) {
182 // find first record in container that has no PreviousProgramID entry
183 SamProgramIterator iter = Begin();
184 SamProgramIterator end = End();
185 for ( ; iter != end; ++iter ) {
186 SamProgram& current = (*iter);
187 if ( !current.HasPreviousProgramID() )
192 cerr << "SamProgramChain ERROR - could not find any record without a PP tag" << endl;
196 /*! \fn const SamProgram& SamProgramChain::First(void) const
197 \brief Fetches first (oldest) record in the chain.
199 This is an overloaded function.
201 N.B. - This function will fail if the chain is empty. If this is possible,
202 check the result of IsEmpty() before calling this function.
204 \return a read-only reference to the first (oldest) program entry
205 \sa Begin(), ConstBegin(), Last()
207 const SamProgram& SamProgramChain::First(void) const {
209 // find first record in container that has no PreviousProgramID entry
210 SamProgramConstIterator iter = ConstBegin();
211 SamProgramConstIterator end = ConstEnd();
212 for ( ; iter != end; ++iter ) {
213 const SamProgram& current = (*iter);
214 if ( !current.HasPreviousProgramID() )
219 cerr << "SamProgramChain ERROR - could not find any record without a PP tag" << endl;
223 /*! \fn int SamProgramChain::IndexOf(const std::string& programId) const
225 \return index of program record if found.
226 Otherwise, returns vector::size() (invalid index).
228 int SamProgramChain::IndexOf(const std::string& programId) const {
229 SamProgramConstIterator begin = ConstBegin();
230 SamProgramConstIterator iter = begin;
231 SamProgramConstIterator end = ConstEnd();
232 for ( ; iter != end; ++iter ) {
233 const SamProgram& current = (*iter);
234 if ( current.ID == programId )
237 return distance( begin, iter );
240 /*! \fn bool SamProgramChain::IsEmpty(void) const
241 \brief Returns \c true if chain contains no records
244 bool SamProgramChain::IsEmpty(void) const {
245 return m_data.empty();
248 /*! \fn SamProgram& SamProgramChain::Last(void)
249 \brief Fetches last (newest) record in the chain.
251 N.B. - This function will fail if the chain is empty. If this is possible,
252 check the result of IsEmpty() before calling this function.
254 \return a modifiable reference to the last (newest) program entry
257 SamProgram& SamProgramChain::Last(void) {
258 // find first record in container that has no NextProgramID entry
259 SamProgramIterator iter = Begin();
260 SamProgramIterator end = End();
261 for ( ; iter != end; ++iter ) {
262 SamProgram& current = (*iter);
263 if ( !current.HasNextProgramID() )
268 cerr << "SamProgramChain ERROR - could not determine last record" << endl;
272 /*! \fn const SamProgram& SamProgramChain::Last(void) const
273 \brief Fetches last (newest) record in the chain.
275 This is an overloaded function.
277 N.B. - This function will fail if the chain is empty. If this is possible,
278 check the result of IsEmpty() before calling this function.
280 \return a read-only reference to the last (newest) program entry
281 \sa End(), ConstEnd(), First()
283 const SamProgram& SamProgramChain::Last(void) const {
284 // find first record in container that has no NextProgramID entry
285 SamProgramConstIterator iter = ConstBegin();
286 SamProgramConstIterator end = ConstEnd();
287 for ( ; iter != end; ++iter ) {
288 const SamProgram& current = (*iter);
289 if ( !current.HasNextProgramID() )
294 cerr << "SamProgramChain ERROR - could not determine last record" << endl;
298 /*! \fn const std::string SamProgramChain::NextIdFor(const std::string& programId) const
300 \return ID of program record, whose PreviousProgramID matches \a programId.
301 Otherwise, returns empty string if none found.
303 const std::string SamProgramChain::NextIdFor(const std::string& programId) const {
305 // find first record in container whose PreviousProgramID matches @programId
306 SamProgramConstIterator iter = ConstBegin();
307 SamProgramConstIterator end = ConstEnd();
308 for ( ; iter != end; ++iter ) {
309 const SamProgram& current = (*iter);
310 if ( !current.HasPreviousProgramID() &&
311 current.PreviousProgramID == programId
322 /*! \fn int SamProgramChain::Size(void) const
323 \brief Returns number of program records in the chain.
326 int SamProgramChain::Size(void) const {
327 return m_data.size();
330 /*! \fn SamProgram& SamProgramChain::operator[](const std::string& programId)
331 \brief Retrieves the modifiable SamProgram record that matches \a programId.
333 NOTE - If the chain contains no read group matching this ID, this function will
334 print an error and terminate.
336 \param programId ID of program record to retrieve
337 \return a modifiable reference to the SamProgram associated with the ID
339 SamProgram& SamProgramChain::operator[](const std::string& programId) {
341 // look up program record matching this ID
342 int index = IndexOf(programId);
344 // if record not found
345 if ( index == (int)m_data.size() ) {
346 cerr << "SamProgramChain ERROR - unknown programId: " << programId << endl;
350 // otherwise return program record at index
351 return m_data.at(index);