// For a given kmer, get the BinaryKmer 'key': // the lower of the kmer vs reverse complement of itself // kmer and kmer_key must NOT point to overlapping memory BinaryKmer bkmer_get_key(const BinaryKmer bkmer, size_t kmer_size) { BinaryKmer bkey; // Get first and last nucleotides Nucleotide first = binary_kmer_first_nuc(bkmer, kmer_size); Nucleotide last = binary_kmer_last_nuc(bkmer); Nucleotide rev_last = dna_nuc_complement(last); if(first < rev_last) return bkmer; // Don't know which is going to be correct -- this will happen 1 in 4 times bkey = binary_kmer_reverse_complement(bkmer, kmer_size); return (binary_kmer_less_than(bkmer, bkey) ? bkmer : bkey); }
Key element_get_key(BinaryKmer * kmer, short kmer_size, Key preallocated_key) { BinaryKmer local_rev_kmer; binary_kmer_initialise_to_zero(&local_rev_kmer); binary_kmer_reverse_complement(kmer, kmer_size, &local_rev_kmer); if (binary_kmer_less_than(local_rev_kmer, *kmer, kmer_size)) { binary_kmer_assignment_operator(*((BinaryKmer *) preallocated_key), local_rev_kmer); } else { binary_kmer_assignment_operator(*((BinaryKmer *) preallocated_key), *kmer); } return preallocated_key; }
dBNode * db_graph_get_next_node(dBNode * current_node, Orientation current_orientation, Orientation * next_orientation, Nucleotide edge, Nucleotide * reverse_edge,dBGraph * db_graph){ BinaryKmer local_copy_of_kmer; binary_kmer_assignment_operator(local_copy_of_kmer, current_node->kmer); BinaryKmer tmp_kmer; dBNode * next_node=NULL; // after the following line tmp_kmer and rev_kmer are pointing to the same B Kmer BinaryKmer* rev_kmer = binary_kmer_reverse_complement(&local_copy_of_kmer,db_graph->kmer_size, &tmp_kmer); if (current_orientation == reverse){ *reverse_edge = binary_kmer_get_last_nucleotide(&local_copy_of_kmer); binary_kmer_assignment_operator(local_copy_of_kmer,*rev_kmer); } else{ *reverse_edge = binary_kmer_get_last_nucleotide(rev_kmer); } binary_kmer_left_shift_one_base_and_insert_new_base_at_right_end(&local_copy_of_kmer, edge, db_graph->kmer_size); //get node from table next_node = hash_table_find(element_get_key(&local_copy_of_kmer,db_graph->kmer_size, &tmp_kmer),db_graph); if (next_node != NULL){ *next_orientation = db_node_get_orientation(&local_copy_of_kmer,next_node,db_graph->kmer_size); } else { // debug char tmpzamseq[db_graph->kmer_size+1]; warn("Cannot find %s so get a NULL node\n", binary_kmer_to_seq(&tmp_kmer, db_graph->kmer_size, tmpzamseq)); } return next_node; }
static bool supernode_is_closed_cycle(const dBNode *nlist, size_t len, BinaryKmer bkmer0, BinaryKmer bkmer1, const dBGraph *db_graph) { Edges edges0, edges1; BinaryKmer shiftkmer; Nucleotide nuc; const size_t kmer_size = db_graph->kmer_size; edges0 = db_node_get_edges_union(db_graph, nlist[0].key); if(edges_get_indegree(edges0, nlist[0].orient) != 1) return false; edges1 = db_node_get_edges_union(db_graph, nlist[len-1].key); if(edges_get_outdegree(edges1, nlist[len-1].orient) != 1) return false; nuc = bkmer_get_last_nuc(bkmer0, nlist[0].orient, kmer_size); shiftkmer = bkmer_shift_add_last_nuc(bkmer1, nlist[len-1].orient, kmer_size, nuc); if(binary_kmers_are_equal(bkmer0, shiftkmer)) return true; shiftkmer = binary_kmer_reverse_complement(shiftkmer, kmer_size); return binary_kmers_are_equal(bkmer0, shiftkmer); }
Orientation db_node_get_orientation(BinaryKmer * k, Element * e, short kmer_size) { if (binary_kmer_comparison_operator(e->kmer, *k) == true) { return forward; } BinaryKmer tmp_kmer; if (binary_kmer_comparison_operator(e->kmer, *(binary_kmer_reverse_complement (k, kmer_size, &tmp_kmer))) == true) { return reverse; } printf("programming error - you have called db_node_get_orientation with a kmer that is neither equal to the kmer in this node, nor its rev comp\n"); char tmpseq1[kmer_size]; char tmpseq2[kmer_size]; printf("Arg 1 Kmer is %s and Arg 2 node kmer is %s\n", binary_kmer_to_seq(k, kmer_size, tmpseq1), binary_kmer_to_seq(&(e->kmer), kmer_size, tmpseq2)); exit(1); }