| 189 | } |
| 190 | |
| 191 | void Stats::statRead(Read* r) { |
| 192 | int len = r->length(); |
| 193 | |
| 194 | mLengthSum += len; |
| 195 | |
| 196 | if(mBufLen < len) { |
| 197 | extendBuffer(max(len + 100, (int)(len * 1.5))); |
| 198 | } |
| 199 | const char* seqstr = r->mSeq->c_str(); |
| 200 | const char* qualstr = r->mQuality->c_str(); |
| 201 | |
| 202 | int kmer = 0; |
| 203 | bool needFullCompute = true; |
| 204 | for(int i=0; i<len; i++) { |
| 205 | char base = seqstr[i]; |
| 206 | char qual = qualstr[i]; |
| 207 | // get last 3 bits |
| 208 | char b = base & 0x07; |
| 209 | |
| 210 | const char q20 = '5'; |
| 211 | const char q30 = '?'; |
| 212 | |
| 213 | mBaseQualHistogram[qual]++; |
| 214 | |
| 215 | if(qual >= q30) { |
| 216 | mCycleQ30Bases[b][i]++; |
| 217 | mCycleQ20Bases[b][i]++; |
| 218 | } else if(qual >= q20) { |
| 219 | mCycleQ20Bases[b][i]++; |
| 220 | } |
| 221 | |
| 222 | mCycleBaseContents[b][i]++; |
| 223 | mCycleBaseQual[b][i] += (qual-33); |
| 224 | |
| 225 | mCycleTotalBase[i]++; |
| 226 | mCycleTotalQual[i] += (qual-33); |
| 227 | |
| 228 | if(base == 'N'){ |
| 229 | needFullCompute = true; |
| 230 | continue; |
| 231 | } |
| 232 | |
| 233 | // 5 bases required for kmer computing |
| 234 | if(i<4) |
| 235 | continue; |
| 236 | |
| 237 | // calc 5 KMER |
| 238 | // 0x3FC == 0011 1111 1100 |
| 239 | if(!needFullCompute){ |
| 240 | int val = base2val(base); |
| 241 | if(val < 0){ |
| 242 | needFullCompute = true; |
| 243 | continue; |
| 244 | } else { |
| 245 | kmer = ((kmer<<2) & 0x3FC ) | val; |
| 246 | mKmer[kmer]++; |
| 247 | } |
| 248 | } else { |
no test coverage detected