void checkKmers(DnaString const & kmer, TVertexDescriptor const & starting_vertex, TVertexDescriptor const & source_vertex, TGraph const & graph, std::vector<VertexLabels> & vertex_vector, boost::unordered_set<TVertexDescriptor> const & free_nodes, boost::unordered_map< std::pair<TVertexDescriptor, TVertexDescriptor>, boost::dynamic_bitset<> > & edge_ids, boost::dynamic_bitset<> const & id_bits, TKmerMap & kmer_map, std::size_t const & kmer_size ) { if (id_bits.none()) return; if (length(kmer) == kmer_size) { KmerLabels new_kmer_label = { starting_vertex, source_vertex, id_bits }; if (kmer_map.count(kmer) == 0) { std::vector<KmerLabels> new_vector(1, new_kmer_label); kmer_map[kmer] = new_vector; } else { kmer_map[kmer].push_back(new_kmer_label); } return; } for (Iterator<TGraph, OutEdgeIterator>::Type out_edge_iterator (graph, source_vertex) ; !atEnd(out_edge_iterator) ; ++out_edge_iterator) { DnaString new_kmer(kmer); TVertexDescriptor const & target_vertex = targetVertex(out_edge_iterator); boost::dynamic_bitset<> new_id_bits(id_bits); if (free_nodes.count(target_vertex) == 0) { seqan::appendValue(new_kmer, vertex_vector[target_vertex].dna); std::pair<TVertexDescriptor, TVertexDescriptor> edge_pair(source_vertex, target_vertex); if (edge_ids.count(edge_pair) == 1) { new_id_bits = id_bits & edge_ids[edge_pair]; } } checkKmers(new_kmer, starting_vertex, target_vertex, graph, vertex_vector, free_nodes, edge_ids, new_id_bits, kmer_map, kmer_size); } }
void check_kmers_simple(DnaString const & kmer, TGraph const & graph, TVertexDescriptor const & source_vertex, std::vector<VertexLabels> & vertex_vector, boost::unordered_set<TVertexDescriptor> const & free_nodes, boost::unordered_map< std::pair<TVertexDescriptor, TVertexDescriptor>, boost::dynamic_bitset<> > & edge_ids, boost::dynamic_bitset<> const & id_bits, TKmerMapSimple & kmer_map, std::size_t const & kmer_size ) { if (id_bits.none()) return; if (length(kmer) == kmer_size) { if (id_bits.all()) return; if (kmer_map.count(kmer) == 0) { kmer_map[kmer] = id_bits; } else { kmer_map[kmer] |= id_bits; } return; } for (Iterator<TGraph, OutEdgeIterator>::Type out_edge_iterator (graph, source_vertex) ; !atEnd(out_edge_iterator) ; ++out_edge_iterator) { DnaString new_kmer(kmer); TVertexDescriptor const & target_vertex = targetVertex(out_edge_iterator); // std::cout << source_vertex << " -> " << target_vertex << std::endl; boost::dynamic_bitset<> new_id_bits(id_bits); if (free_nodes.count(target_vertex) == 0) { seqan::appendValue(new_kmer, vertex_vector[target_vertex].dna); std::pair<TVertexDescriptor, TVertexDescriptor> edge_pair(source_vertex, target_vertex); if (edge_ids.count(edge_pair) == 1) { new_id_bits = id_bits & edge_ids[edge_pair]; } } check_kmers_simple(new_kmer, graph, target_vertex, vertex_vector, free_nodes, edge_ids, new_id_bits, kmer_map, kmer_size); } }
edge_pair delaunay_dc2(vertex v[], size_t n, bool div_by_x, vertex_buffer p) { edge_pair ldo_ldi, rdi_rdo; edge a, b, c, ldo, ldi, rdo, rdi, basel, lcand, rcand, temp; vertex *v_l, *v_r; size_t median, v_l_n, v_r_n; bool lcand_valid, rcand_valid; if (n == 2) { // for two vertices, return the two directed edges between them if (point_lte(p.val(v[0]), p.val(v[1]), div_by_x)) { a = make_edge(v[0], v[1]); } else { a = make_edge(v[1], v[0]); } return edge_pair(a, a.sym()); } else if (n == 3) { // for three vertices a = make_edge(); b = make_edge(); splice(a.sym(), b); // order the vertices on the right axis bool zero_lte_one = point_lte(p.val(v[0]), p.val(v[1]), div_by_x); bool one_lte_two = point_lte(p.val(v[1]), p.val(v[2]), div_by_x); bool two_lte_zero = point_lte(p.val(v[2]), p.val(v[0]), div_by_x); vertex first, second, third; if (zero_lte_one) { if (one_lte_two) { first = v[0]; second = v[1]; third = v[2]; } else { if (two_lte_zero) { first = v[2]; second = v[0]; third = v[1]; } else { first = v[0]; second = v[2]; third = v[1]; } } } else { if (one_lte_two) { if (two_lte_zero) { first = v[1]; second = v[2]; third = v[0]; } else { first = v[1]; second = v[0]; third = v[2]; } } else { first = v[2]; second = v[1]; third = v[0]; } } a.set_org(first); a.set_dst(second); b.set_org(second); b.set_dst(third); if (p.orient2d(first, second, third) > 0) { c = connect(b, a); return edge_pair(a, b.sym()); } else if (p.orient2d(first, third, second) > 0) { c = connect(b, a); return edge_pair(c.sym(), c); } else { // the points are collinear return edge_pair(a, b.sym()); } } else { // n >= 4 // div_by_x tells whether this recursive case is splitting by x // divide v into left half v_l, right half v_r median = lexico_partition(v, n, div_by_x, p); v_l = v; v_l_n = median + 1; // +1 ensures that the lower partition has >=2 v_r = (v + v_l_n); v_r_n = (n - v_l_n); // recursive calls split in opposite axis; *do and *di are flipped! // must merge on the current axis, however ldo_ldi = delaunay_dc2(v_l, v_l_n, !div_by_x, p); ldo = ldo_ldi[0]; // ccw, so right face is open ldi = ldo_ldi[1]; // cw, so left face is open rdi_rdo = delaunay_dc2(v_r, v_r_n, !div_by_x, p); rdi = rdi_rdo[0]; // ccw, so right face is open rdo = rdi_rdo[1]; // cw, so left face is open // move *di, *do into the correct "leftmost", "rightmost" for level if (div_by_x) { while (point_lte(p.val(ldo.rprev().org()), p.val(ldo.org()), div_by_x)) { ldo = ldo.rprev(); } while (point_lte(p.val(ldi.org()), p.val(ldi.lnext().org()), div_by_x)) { ldi = ldi.lnext(); } while (point_lte(p.val(rdi.rprev().org()), p.val(rdi.org()), div_by_x)) { rdi = rdi.rprev(); } while (point_lte(p.val(rdo.org()), p.val(rdo.lnext().org()), div_by_x)) { rdo = rdo.lnext(); } } else { while (point_lte(p.val(ldo.rnext().org()), p.val(ldo.org()), div_by_x)) { ldo = ldo.rnext(); } while (point_lte(p.val(ldi.org()), p.val(ldi.lprev().org()), div_by_x)) { ldi = ldi.lprev(); } while (point_lte(p.val(rdi.rnext().org()), p.val(rdi.org()), div_by_x)) { rdi = rdi.rnext(); } while (point_lte(p.val(rdo.org()), p.val(rdo.lprev().org()), div_by_x)) { rdo = rdo.lprev(); } } // loop to compute lower common tangent of l and r while (true) { if (p.leftof(rdi.org(), ldi.org(), ldi.dst())) { ldi = ldi.lnext(); } else if (p.rightof(ldi.org(), rdi.org(), rdi.dst())) { //rdi = rdi.rprev(); // Guibas and Stolfi wrong here? rdi = rdi.rnext(); } else { break; } } // create the first cross edge basel from rdi.org to ldi.org basel = connect(rdi.sym(), ldi); if (ldi.org() == ldo.org()) { ldo = basel.sym(); } if (rdi.org() == rdo.org()) { rdo = basel; } // merge loop while (true) { // is lcand valid? lcand = basel.sym().onext(); lcand_valid = p.rightof(lcand.dst(), basel.org(), basel.dst()); if (lcand_valid) { while (p.incircle(basel.dst(), basel.org(), lcand.dst(), lcand.onext().dst()) > 0) { temp = lcand.onext(); delete_edge(lcand); lcand = temp; } } // is rcand valid? rcand = basel.oprev(); rcand_valid = p.rightof(rcand.dst(), basel.org(), basel.dst()); if (rcand_valid) { while (p.incircle(basel.dst(), basel.org(), rcand.dst(), rcand.oprev().dst()) > 0) { temp = rcand.oprev(); delete_edge(rcand); rcand = temp; } } lcand_valid = p.rightof(lcand.dst(), basel.org(), basel.dst()); rcand_valid = p.rightof(rcand.dst(), basel.org(), basel.dst()); // if both lcand and rcand are invalid, // then basel is the upper common tangent // ... break out of merge loop if ((not lcand_valid) and (not rcand_valid)) { break; } // the next cross edge is to be connected to either // lcand.dst() or rcand.dst() // if both valid, choose the appropriate one using incircle test if ((not lcand_valid) or ((rcand_valid and (p.incircle(lcand.dst(), lcand.org(), rcand.org(), rcand.dst())) > 0))) { // add cross edge basel from rcand.dst() to basel.dst() basel = connect(rcand, basel.sym()); } else { // add cross edge basel from basel.org() to lcand.dst() basel = connect(basel.sym(), lcand.sym()); } } return edge_pair(ldo, rdo); } }
// outputs the edge_pair (le, re) // le: counterclockwise convex hull edge out of the leftmost vertex // re: clockwise convex hull edge out of the rightmost vertex edge_pair delaunay_dc(vertex v[], size_t n, vertex_buffer p) { // assumes that v is sorted in lexicographic order edge_pair ldo_ldi, rdi_rdo; edge a, b, c, ldo, ldi, rdo, rdi, basel, lcand, rcand, temp; vertex *v_l, *v_r; size_t v_l_n, v_r_n; bool lcand_valid, rcand_valid; if (n == 2) { // for two vertices, return the two directed edges between them a = make_edge(v[0], v[1]); return edge_pair(a, a.sym()); } else if (n == 3) { // for three vertices a = make_edge(); b = make_edge(); splice(a.sym(), b); a.set_org(v[0]); a.set_dst(v[1]); b.set_org(v[1]); b.set_dst(v[2]); if (p.orient2d(v[0], v[1], v[2]) > 0) { c = connect(b, a); return edge_pair(a, b.sym()); } else if (p.orient2d(v[0], v[2], v[1]) > 0) { c = connect(b, a); return edge_pair(c.sym(), c); } else { // the points are collinear return edge_pair(a, b.sym()); } } else { // n >= 4 // divide v into left half v_l, right half v_r v_l = v; v_l_n = n/2; v_r = (v + v_l_n); v_r_n = (n - v_l_n); ldo_ldi = delaunay_dc(v_l, v_l_n, p); ldo = ldo_ldi[0]; ldi = ldo_ldi[1]; rdi_rdo = delaunay_dc(v_r, v_r_n, p); rdi = rdi_rdo[0]; rdo = rdi_rdo[1]; // loop to compute lower common tangent of l and r while (true) { if (p.leftof(rdi.org(), ldi.org(), ldi.dst())) { ldi = ldi.lnext(); } else if (p.rightof(ldi.org(), rdi.org(), rdi.dst())) { //rdi = rdi.rprev(); // Guibas and Stolfi wrong here? rdi = rdi.rnext(); } else { break; } } // create the first cross edge basel from rdi.org to ldi.org basel = connect(rdi.sym(), ldi); if (ldi.org() == ldo.org()) { ldo = basel.sym(); } if (rdi.org() == rdo.org()) { rdo = basel; } // merge loop while (true) { // is lcand valid? lcand = basel.sym().onext(); lcand_valid = p.rightof(lcand.dst(), basel.org(), basel.dst()); if (lcand_valid) { while (p.incircle(basel.dst(), basel.org(), lcand.dst(), lcand.onext().dst()) > 0) { temp = lcand.onext(); delete_edge(lcand); lcand = temp; } } // is rcand valid? rcand = basel.oprev(); rcand_valid = p.rightof(rcand.dst(), basel.org(), basel.dst()); if (rcand_valid) { while (p.incircle(basel.dst(), basel.org(), rcand.dst(), rcand.oprev().dst()) > 0) { temp = rcand.oprev(); delete_edge(rcand); rcand = temp; } } lcand_valid = p.rightof(lcand.dst(), basel.org(), basel.dst()); rcand_valid = p.rightof(rcand.dst(), basel.org(), basel.dst()); // if both lcand and rcand are invalid, // then basel is the upper common tangent // ... break out of merge loop if ((not lcand_valid) and (not rcand_valid)) { break; } // the next cross edge is to be connected to either // lcand.dst() or rcand.dst() // if both valid, choose the appropriate one using incircle test if ((not lcand_valid) or ((rcand_valid and (p.incircle(lcand.dst(), lcand.org(), rcand.org(), rcand.dst())) > 0))) { // add cross edge basel from rcand.dst() to basel.dst() basel = connect(rcand, basel.sym()); } else { // add cross edge basel from basel.org() to lcand.dst() basel = connect(basel.sym(), lcand.sym()); } } return edge_pair(ldo, rdo); } }