1 // ***************************************************************************
2 // SamProgramChain.cpp (c) 2011 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // ---------------------------------------------------------------------------
5 // Last modified: 19 April 2011 (DB)
6 // ---------------------------------------------------------------------------
7 // Provides methods for operating on a SamProgram record "chain"
8 // ***************************************************************************
10 #include <api/SamProgramChain.h>
11 using namespace BamTools;
18 /*! \class BamTools::SamProgramChain
19 \brief Sorted container "chain" of SamProgram records.
21 Provides methods for operating on a collection of SamProgram records.
23 N.B. - Underlying container is *NOT* ordered by linkage, but by order of
24 appearance in SamHeader and subsequent Add() calls. Using the current
25 iterators will not allow you to step through the header's program history.
26 Instead use First()/Last() to access oldest/newest records, respectively.
29 /*! \fn SamProgramChain::SamProgramChain(void)
32 SamProgramChain::SamProgramChain(void) { }
34 /*! \fn SamProgramChain::SamProgramChain(const SamProgramChain& other)
35 \brief copy constructor
37 SamProgramChain::SamProgramChain(const SamProgramChain& other)
38 : m_data(other.m_data)
41 /*! \fn SamProgramChain::~SamProgramChain(void)
44 SamProgramChain::~SamProgramChain(void) { }
46 /*! \fn void SamProgramChain::Add(SamProgram& program)
47 \brief Appends a program to program chain.
49 Duplicate entries are silently discarded.
51 N.B. - Underlying container is *NOT* ordered by linkage, but by order of
52 appearance in SamHeader and subsequent Add() calls. Using the current
53 iterators will not allow you to step through the header's program history.
54 Instead use First()/Last() to access oldest/newest records, respectively.
56 \param program entry to be appended
58 void SamProgramChain::Add(SamProgram& program) {
60 // ignore duplicated records
61 if ( Contains(program) )
64 // if other programs already in chain, try to find the "next" record
65 // tries to match another record's PPID with @program's ID
67 program.NextProgramID = NextIdFor(program.ID);
69 // store program record
70 m_data.push_back(program);
73 /*! \fn void SamProgramChain::Add(const std::vector<SamProgram>& programs)
74 \brief Appends a batch of programs to the end of the chain.
76 This is an overloaded function.
78 \param programs batch of program records to append
81 void SamProgramChain::Add(std::vector<SamProgram>& programs) {
82 vector<SamProgram>::iterator pgIter = programs.begin();
83 vector<SamProgram>::iterator pgEnd = programs.end();
84 for ( ; pgIter != pgEnd; ++pgIter )
88 /*! \fn SamProgramIterator SamProgramChain::Begin(void)
89 \return an STL iterator pointing to the first (oldest) program record
90 \sa ConstBegin(), End(), First()
92 SamProgramIterator SamProgramChain::Begin(void) {
93 return m_data.begin();
96 /*! \fn SamProgramConstIterator SamProgramChain::Begin(void) const
97 \return an STL const_iterator pointing to the first (oldest) program record
99 This is an overloaded function.
101 \sa ConstBegin(), End(), First()
103 SamProgramConstIterator SamProgramChain::Begin(void) const {
104 return m_data.begin();
107 /*! \fn void SamProgramChain::Clear(void)
108 \brief Clears all program records.
110 void SamProgramChain::Clear(void) {
114 /*! \fn SamProgramConstIterator SamProgramChain::ConstBegin(void) const
115 \return an STL const_iterator pointing to the first (oldest) program record
116 \sa Begin(), ConstEnd(), First()
118 SamProgramConstIterator SamProgramChain::ConstBegin(void) const {
119 return m_data.begin();
122 /*! \fn SamProgramConstIterator SamProgramChain::ConstEnd(void) const
123 \return an STL const_iterator pointing to the imaginary entry after the last (newest) program record
124 \sa ConstBegin(), End(), Last()
126 SamProgramConstIterator SamProgramChain::ConstEnd(void) const {
130 /*! \fn bool SamProgramChain::Contains(const SamProgram& program) const
131 \brief Returns true if chains has this program record (matching on ID).
133 This is an overloaded function.
135 \param program SamProgram to search for
136 \return \c true if chain contains program (matching on ID)
138 bool SamProgramChain::Contains(const SamProgram& program) const {
139 return Contains(program.ID);
142 /*! \fn bool SamProgramChain::Contains(const std::string& programId) const
143 \brief Returns true if chains has a program record with this ID
144 \param programId search for program matching this ID
145 \return \c true if chain contains a program record with this ID
147 bool SamProgramChain::Contains(const std::string& programId) const {
148 return ( IndexOf(programId) != (int)m_data.size() );
151 /*! \fn SamProgramIterator SamProgramChain::End(void)
152 \return an STL iterator pointing to the imaginary entry after the last (newest) program record
153 \sa Begin(), ConstEnd(), Last()
155 SamProgramIterator SamProgramChain::End(void) {
159 /*! \fn SamProgramConstIterator SamProgramChain::End(void) const
160 \return an STL const_iterator pointing to the imaginary entry after the last (newest) program record
162 This is an overloaded function.
164 \sa Begin(), ConstEnd(), Last()
166 SamProgramConstIterator SamProgramChain::End(void) const {
170 /*! \fn SamProgram& SamProgramChain::First(void)
171 \brief Fetches first (oldest) record in the chain.
173 N.B. - This function will fail if the chain is empty. If this is possible,
174 check the result of IsEmpty() before calling this function.
176 \return a modifiable reference to the first (oldest) program entry
179 SamProgram& SamProgramChain::First(void) {
181 // find first record in container that has no PreviousProgramID entry
182 SamProgramIterator iter = Begin();
183 SamProgramIterator end = End();
184 for ( ; iter != end; ++iter ) {
185 SamProgram& current = (*iter);
186 if ( !current.HasPreviousProgramID() )
191 cerr << "SamProgramChain ERROR - could not find any record without a PP tag" << endl;
195 /*! \fn const SamProgram& SamProgramChain::First(void) const
196 \brief Fetches first (oldest) record in the chain.
198 This is an overloaded function.
200 N.B. - This function will fail if the chain is empty. If this is possible,
201 check the result of IsEmpty() before calling this function.
203 \return a read-only reference to the first (oldest) program entry
204 \sa Begin(), ConstBegin(), Last()
206 const SamProgram& SamProgramChain::First(void) const {
208 // find first record in container that has no PreviousProgramID entry
209 SamProgramConstIterator iter = ConstBegin();
210 SamProgramConstIterator end = ConstEnd();
211 for ( ; iter != end; ++iter ) {
212 const SamProgram& current = (*iter);
213 if ( !current.HasPreviousProgramID() )
218 cerr << "SamProgramChain ERROR - could not find any record without a PP tag" << endl;
222 /*! \fn int SamProgramChain::IndexOf(const std::string& programId) const
224 \return index of program record if found.
225 Otherwise, returns vector::size() (invalid index).
227 int SamProgramChain::IndexOf(const std::string& programId) const {
228 SamProgramConstIterator begin = ConstBegin();
229 SamProgramConstIterator iter = begin;
230 SamProgramConstIterator end = ConstEnd();
231 for ( ; iter != end; ++iter ) {
232 const SamProgram& current = (*iter);
233 if ( current.ID == programId )
236 return distance( begin, iter );
239 /*! \fn bool SamProgramChain::IsEmpty(void) const
240 \brief Returns \c true if chain contains no records
243 bool SamProgramChain::IsEmpty(void) const {
244 return m_data.empty();
247 /*! \fn SamProgram& SamProgramChain::Last(void)
248 \brief Fetches last (newest) record in the chain.
250 N.B. - This function will fail if the chain is empty. If this is possible,
251 check the result of IsEmpty() before calling this function.
253 \return a modifiable reference to the last (newest) program entry
256 SamProgram& SamProgramChain::Last(void) {
257 // find first record in container that has no NextProgramID entry
258 SamProgramIterator iter = Begin();
259 SamProgramIterator end = End();
260 for ( ; iter != end; ++iter ) {
261 SamProgram& current = (*iter);
262 if ( !current.HasNextProgramID() )
267 cerr << "SamProgramChain ERROR - could not determine last record" << endl;
271 /*! \fn const SamProgram& SamProgramChain::Last(void) const
272 \brief Fetches last (newest) record in the chain.
274 This is an overloaded function.
276 N.B. - This function will fail if the chain is empty. If this is possible,
277 check the result of IsEmpty() before calling this function.
279 \return a read-only reference to the last (newest) program entry
280 \sa End(), ConstEnd(), First()
282 const SamProgram& SamProgramChain::Last(void) const {
283 // find first record in container that has no NextProgramID entry
284 SamProgramConstIterator iter = ConstBegin();
285 SamProgramConstIterator end = ConstEnd();
286 for ( ; iter != end; ++iter ) {
287 const SamProgram& current = (*iter);
288 if ( !current.HasNextProgramID() )
293 cerr << "SamProgramChain ERROR - could not determine last record" << endl;
297 /*! \fn const std::string SamProgramChain::NextIdFor(const std::string& programId) const
299 \return ID of program record, whose PreviousProgramID matches \a programId.
300 Otherwise, returns empty string if none found.
302 const std::string SamProgramChain::NextIdFor(const std::string& programId) const {
304 // find first record in container whose PreviousProgramID matches @programId
305 SamProgramConstIterator iter = ConstBegin();
306 SamProgramConstIterator end = ConstEnd();
307 for ( ; iter != end; ++iter ) {
308 const SamProgram& current = (*iter);
309 if ( !current.HasPreviousProgramID() &&
310 current.PreviousProgramID == programId
321 /*! \fn int SamProgramChain::Size(void) const
322 \brief Returns number of program records in the chain.
325 int SamProgramChain::Size(void) const {
326 return m_data.size();
329 /*! \fn SamProgram& SamProgramChain::operator[](const std::string& programId)
330 \brief Retrieves the modifiable SamProgram record that matches \a programId.
332 NOTE - If the chain contains no read group matching this ID, this function will
333 print an error and terminate.
335 \param programId ID of program record to retrieve
336 \return a modifiable reference to the SamProgram associated with the ID
338 SamProgram& SamProgramChain::operator[](const std::string& programId) {
340 // look up program record matching this ID
341 int index = IndexOf(programId);
343 // if record not found
344 if ( index == (int)m_data.size() ) {
345 cerr << "SamProgramChain ERROR - unknown programId: " << programId << endl;
349 // otherwise return program record at index
350 return m_data.at(index);