| 306 | } |
| 307 | |
| 308 | string Evaluator::evalAdapterAndReadNum(long& readNum, bool isR2) { |
| 309 | string filename = mOptions->in1; |
| 310 | if(isR2) |
| 311 | filename = mOptions->in2; |
| 312 | FastqReader reader(filename); |
| 313 | // stat up to 256K reads |
| 314 | const long READ_LIMIT = 256*1024; |
| 315 | const long BASE_LIMIT = 151 * READ_LIMIT; |
| 316 | long records = 0; |
| 317 | long bases = 0; |
| 318 | size_t firstReadPos = 0; |
| 319 | |
| 320 | size_t bytesRead; |
| 321 | size_t bytesTotal; |
| 322 | |
| 323 | Read** loadedReads = new Read*[READ_LIMIT]; |
| 324 | memset(loadedReads, 0, sizeof(Read*)*READ_LIMIT); |
| 325 | bool reachedEOF = false; |
| 326 | bool first = true; |
| 327 | |
| 328 | while(records < READ_LIMIT && bases < BASE_LIMIT) { |
| 329 | Read* r = reader.read(); |
| 330 | if(!r) { |
| 331 | reachedEOF = true; |
| 332 | break; |
| 333 | } |
| 334 | if(first) { |
| 335 | reader.getBytes(bytesRead, bytesTotal); |
| 336 | firstReadPos = bytesRead; |
| 337 | first = false; |
| 338 | } |
| 339 | int rlen = r->length(); |
| 340 | bases += rlen; |
| 341 | loadedReads[records] = r; |
| 342 | records++; |
| 343 | } |
| 344 | |
| 345 | readNum = 0; |
| 346 | if(reachedEOF){ |
| 347 | readNum = records; |
| 348 | } else if(records>0) { |
| 349 | // by the way, update readNum so we don't need to evaluate it if splitting output is enabled |
| 350 | reader.getBytes(bytesRead, bytesTotal); |
| 351 | double bytesPerRead = (double)(bytesRead - firstReadPos) / (double) records; |
| 352 | // increase it by 1% since the evaluation is usually a bit lower due to bad quality causes lower compression rate |
| 353 | readNum = (long) (bytesTotal*1.01 / bytesPerRead); |
| 354 | } |
| 355 | |
| 356 | // we need at least 10000 valid records to evaluate |
| 357 | if(records < 10000) { |
| 358 | for(int r=0; r<records; r++) { |
| 359 | delete loadedReads[r]; |
| 360 | loadedReads[r] = NULL; |
| 361 | } |
| 362 | delete[] loadedReads; |
| 363 | return ""; |
| 364 | } |
| 365 | |