source: tags/arb_5.3/GENOM_IMPORT/SequenceBuffer.cxx

Last change on this file was 5814, checked in by westram, 15 years ago
  • fixed memory leak (GEN_positionPtr used free() instead of GEN_free_position())
  • cleanup static dynamic data (after import)
File size: 4.8 KB
Line 
1// ================================================================ //
2//                                                                  //
3//   File      : SequenceBuffer.cxx                                 //
4//   Purpose   :                                                    //
5//                                                                  //
6//   Coded by Ralf Westram (coder@reallysoft.de) in December 2006   //
7//   Institute of Microbiology (Technical University Munich)        //
8//   http://www.arb-home.de/                                        //
9//                                                                  //
10// ================================================================ //
11#include "SequenceBuffer.h"
12
13using namespace std;
14
15void CharCounter::clear() {
16    for (int i = 0; i<256; i++) count[i] = 0;
17    all = 0;
18}
19
20void CharCounter::countChars(const string& line)
21{
22    string::const_iterator e = line.end();
23    for (string::const_iterator i = line.begin(); i != e; ++i) {
24        ++count[static_cast<unsigned char>(*i)];
25        ++all;
26    }
27}
28
29// --------------------------------------------------------------------------------
30
31void BaseCounter::calcOverallCounter()
32{
33    gi_assert(char_count.Null()); // may not be used for line counted BaseCounter
34    gi_assert(count[BC_ALL] == 0); // already have a value for overall counter
35
36    size_t all                          = 0;
37    for (int i = 0; i<BC_ALL; ++i) all += count[i];
38
39    if (count[BC_ALL] == 0) {   // got no value for all counter -> use calculated value
40        count[BC_ALL] = all;
41    }
42}
43
44void BaseCounter::checkOverallCounter() const
45{
46    catchUpWithLineCounter();
47
48    size_t all = 0;
49
50    for (int i = 0; i<BC_ALL; ++i) all += count[i];
51
52    gi_assert(count[BC_ALL]>0); // forgot to call calcOverallCounter ?
53    if (count[BC_ALL] != all) {
54        throw GBS_global_string("Overall bp (=%u) does not match sum (=%u) of single bases (Occurrence: '%s')",
55                                count[BC_ALL], all, source.c_str());
56    }
57}
58
59void BaseCounter::catchUpWithLineCounter() const
60{
61    if (!char_count.Null()) {
62        CharCounter& cc  = const_cast<CharCounter&>(*char_count);
63        size_t       all = cc.getCount(); // all bases
64
65        if (all>0) { // anything counted ?
66            size_t  normal  = 0; // normal bases
67            size_t *mucount = const_cast<size_t*>(count);
68
69            static const unsigned char normalChars[] = "aAcCgGtTuU";
70            static Base normalBase[] = { BC_A, BC_A, BC_C, BC_C, BC_G, BC_G, BC_T, BC_T, BC_T, BC_T };
71
72            // count standard bases
73            for (unsigned i = 0; normalChars[i]; ++i) {
74                size_t bp               = cc.getCount(normalChars[i]);
75                mucount[normalBase[i]] += bp;
76                normal                 += bp;
77            }
78
79            mucount[BC_ALL]   += all;
80            mucount[BC_OTHER] += all-normal;
81
82            cc.clear(); // reset counter
83        }
84    }
85}
86
87void BaseCounter::startLineCounter()
88{
89    gi_assert(char_count.Null());
90    char_count = new CharCounter;
91}
92
93
94void BaseCounter::expectEqual(const BaseCounter& other) const {
95    // expect counters to be equal or throw error
96
97    catchUpWithLineCounter();
98    other.catchUpWithLineCounter();
99
100    checkOverallCounter();
101    other.checkOverallCounter();
102
103    for (int i = 0; i<BC_COUNTERS; ++i) {
104        if (count[i] != other.count[i]) { // mismatch in counter
105            string error = "Base counter mismatch";
106            error        = error+"\n  "+source+"<>"+other.source;
107
108            for (; i<BC_COUNTERS; ++i) {
109                if (count[i] != other.count[i]) { // mismatch in counter
110                    string whichCounter;
111
112                    if (i == BC_OTHER)      whichCounter = "other";
113                    else if (i == BC_ALL)   whichCounter = "overall";
114                    else                    whichCounter = "ACGT"[i];
115
116                    error = error+"\n  "+whichCounter+": "+GBS_global_string("%u <> %u", count[i], other.count[i]);
117                }
118            }
119
120            throw error;
121        }
122    }
123}
124
125// --------------------------------------------------------------------------------
126
127SequenceBuffer::~SequenceBuffer() {
128    delete [] seq;
129}
130
131const char *SequenceBuffer::getSequence() const {
132    gi_assert(!seq);            // don't call twice!
133    if (!seq) {
134        size_t len = baseCounter.getCount(BC_ALL);
135        seq        = new char[len+1];
136
137        char              *sp = seq;
138        stringVectorCIter  e  = lines.end();
139
140        for (stringVectorCIter i = lines.begin(); i != e; ++i) {
141            size_t ilen  = i->length();
142            memcpy(sp, i->c_str(), ilen);
143            sp         += ilen;
144        }
145
146#if defined(DEBUG)
147        size_t stored = sp-seq;
148        gi_assert(stored == len);
149#endif // DEBUG
150
151        seq[len] = 0;
152    }
153    return seq;
154}
155
156
Note: See TracBrowser for help on using the repository browser.