// Traverse from node0 -> node1 static void traverse_5pflank(BreakpointCaller *caller, GraphCrawler *crawler, dBNode node0, dBNode node1) { const dBGraph *db_graph = crawler->cache.db_graph; dBNode next_nodes[4]; Nucleotide next_nucs[4]; size_t i, num_next; BinaryKmer bkmer0 = db_node_get_bkmer(db_graph, node0.key); num_next = db_graph_next_nodes(db_graph, bkmer0, node0.orient, db_node_edges(db_graph, node0.key, 0), next_nodes, next_nucs); // Find index of previous node for(i = 0; i < num_next && !db_nodes_are_equal(next_nodes[i],node1); i++) {} ctx_assert(i < num_next && db_nodes_are_equal(next_nodes[i],node1)); kmer_run_buf_reset(&caller->koruns_5p); kmer_run_buf_reset(&caller->koruns_5p_ended); kmer_run_buf_reset(&caller->flank5p_run_buf); // Go backwards to get 5p flank // NULL means loop from 0..(ncols-1) graph_crawler_fetch(crawler, node0, next_nodes, next_nucs, i, num_next, NULL, db_graph->num_of_cols, gcrawler_flank5p_stop_at_ref_covg, gcrawler_flank5p_finish_ref_covg, caller); }
static inline void infer_edges_node(hkey_t hkey, bool add_all_edges, const dBGraph *db_graph, size_t *num_nodes_modified) { BinaryKmer bkmer = db_node_bkmer(db_graph, hkey); Edges *edges = &db_node_edges(db_graph, hkey, 0); size_t col; // Create coverages that are zero or one depending on if node has colour Covg covgs[db_graph->num_of_cols]; for(col = 0; col < db_graph->num_of_cols; col++) covgs[col] = db_node_has_col(db_graph, hkey, col); (*num_nodes_modified) += (add_all_edges ? infer_all_edges(bkmer, edges, covgs, db_graph) : infer_pop_edges(bkmer, edges, covgs, db_graph)); }
static inline int infer_edges_node(hkey_t hkey, bool add_all_edges, Covg *tmp_covgs, const dBGraph *db_graph, size_t *num_nodes_modified) { BinaryKmer bkmer = db_node_get_bkmer(db_graph, hkey); Edges *edges = &db_node_edges(db_graph, hkey, 0); size_t col; // Create coverages that are zero or one depending on if node has colour if(db_graph->col_covgs == NULL) { for(col = 0; col < db_graph->num_of_cols; col++) tmp_covgs[col] = db_node_has_col(db_graph, hkey, col); } else { tmp_covgs = &db_node_covg(db_graph, hkey, 0); } (*num_nodes_modified) += (add_all_edges ? infer_all_edges(bkmer, edges, tmp_covgs, db_graph) : infer_pop_edges(bkmer, edges, tmp_covgs, db_graph)); return 0; // => keep iterating }
// `fork_node` is a node with outdegree > 1 void find_bubbles(BubbleCaller *caller, dBNode fork_node) { graph_cache_reset(&caller->cache); const dBGraph *db_graph = caller->db_graph; GraphCache *cache = &caller->cache; GraphWalker *wlk = &caller->wlk; RepeatWalker *rptwlk = &caller->rptwlk; // char tmpstr[MAX_KMER_SIZE+3]; // db_node_to_str(db_graph, fork_node, tmpstr); // status("Calling from %s", tmpstr); dBNode nodes[4]; Nucleotide bases[4]; size_t i, num_next, num_edges_in_col; BinaryKmer fork_bkmer = db_node_get_bkmer(db_graph, fork_node.key); num_next = db_graph_next_nodes(db_graph, fork_bkmer, fork_node.orient, db_node_edges(db_graph, fork_node.key, 0), nodes, bases); // loop over alleles, then colours Colour colour, colours_loaded = db_graph->num_of_cols; bool node_has_col[4]; uint32_t pathid; for(colour = 0; colour < colours_loaded; colour++) { if(!db_node_has_col(db_graph, fork_node.key, colour)) continue; // Determine if this fork is a fork in the current colour num_edges_in_col = 0; for(i = 0; i < num_next; i++) { node_has_col[i] = (db_node_has_col(db_graph, nodes[i].key, colour) > 0); num_edges_in_col += node_has_col[i]; } graph_walker_setup(wlk, true, colour, colour, db_graph); for(i = 0; i < num_next; i++) { if(node_has_col[i]) { graph_walker_start(wlk, fork_node); graph_walker_force(wlk, nodes[i], num_edges_in_col > 1); pathid = graph_crawler_load_path_limit(cache, nodes[i], wlk, rptwlk, caller->prefs.max_allele_len); graph_walker_finish(wlk); graph_crawler_reset_rpt_walker(rptwlk, cache, pathid); } } } // Set up 5p flank caller->flank5p.b[0] = db_node_reverse(fork_node); caller->flank5p.len = 0; // set to one to signify we haven't fetched flank yet }