void HashGraph::RefreshVertices(unsigned minCount) { #pragma omp parallel for for (int64 i = 0; i < (int64)table_size; ++i) { HashNode *node = table[i]; HashNode *prev = NULL; while (node != NULL) { if (node->IsDead() || node->Count() < minCount) { #pragma omp atomic --num_nodes; if (prev == NULL) { table[i] = node->next; FreeNode(node, omp_get_thread_num()); node = table[i]; } else { prev->next = node->next; FreeNode(node, omp_get_thread_num()); node = prev->next; } } else { node->ClearStatus(); prev = node; node = prev->next; } } } }
double HashGraph::AverageCoverage() { long long sum = 0; uint64 valid = 0; for (int64 i = 0; i < table_size; ++i) { for (HashNode *node = table[i]; node; node = node->next) { sum += node->Count(); ++valid; } } return 1.0 * sum / valid; }
double HashGraph::MedianCoverage() { vector<int> v; v.reserve(num_nodes); for (int64 i = 0; i < table_size; ++i) { for (HashNode *node = table[i]; node; node = node->next) { v.push_back(node->Count()); } } nth_element(v.begin(), v.begin() + v.size()/2, v.end()); return *(v.begin() + v.size()/2); }
int64 HashGraph::Assemble(vector<Contig> &contigs) { contigs.resize(0); int tangle = 0; omp_lock_t lockContigs; omp_init_lock(&lockContigs); #pragma omp parallel for for (int64 i = 0; i < (int64)table_size; ++i) { for (HashNode *node = table[i]; node != NULL; node = node->next) { if (!node->Lock(omp_get_thread_num())) continue; Contig contig; contig.SetContent(node->kmer, kmerLength); contig.sum_coverage = node->Count(); contig.is_tangle = false; if (!node->kmer.IsPalindrome()) { for (int strand = 0; strand < 2; ++strand) { KmerNodeAdapter adp = GetNodeAdapter(contig.GetEndKmer()); KmerNodeAdapter next(NULL); while (true) { if (!GetNextNodeAdapter(adp, next)) break; if (next.GetLockID() == omp_get_thread_num() && IsLoop(contig, next)) break; if (!next.LockPreempt(omp_get_thread_num())) goto FAIL; contig.AddNucleotide(BitOperation::bitToIndex[adp.OutEdges()]); adp = next; contig.sum_coverage += next.Count(); } if (adp.OutDegree() == 0) contig.is_tangle = true; contig.ReverseComplement(); } } if (contig.is_tangle) { #pragma omp atomic ++tangle; } omp_set_lock(&lockContigs); contigs.push_back(contig); omp_unset_lock(&lockContigs); FAIL: ; } } omp_destroy_lock(&lockContigs); ClearStatus(); LogMessage("tangle %d total %d\n", tangle, contigs.size()); return contigs.size(); }