static void test_walk(GraphWalker *gwlk, RepeatWalker *rptwlk,
                      dBNode node0, dBNodeBuffer *nbuf,
                      const dBGraph *graph,
                      size_t expnkmers, const char *ans)
{
  db_node_buf_reset(nbuf);
  graph_walker_init(gwlk, graph, 0, 0, node0);

  do {
    db_node_buf_add(nbuf, gwlk->node);
  }
  while(graph_walker_next(gwlk) && rpt_walker_attempt_traverse(rptwlk, gwlk));

  // db_nodes_print(nbuf->data, nbuf->len, graph, stdout);
  // printf("\n");
  // printf("%s\n", graph_step_str[gwlk->last_step.status]);

  TASSERT2(nbuf->len == expnkmers, "%zu / %zu", nbuf->len, expnkmers);

  char tmp[nbuf->len+MAX_KMER_SIZE];
  db_nodes_to_str(nbuf->data, nbuf->len, graph, tmp);
  TASSERT2(strcmp(tmp,ans) == 0, "%s vs %s", tmp, ans);

  graph_walker_finish(gwlk);
  rpt_walker_fast_clear(rptwlk, nbuf->data, nbuf->len);
}
Beispiel #2
0
// Check we can walk along a set of nodes through the graph
// If @allow_extend is true, traverse past the end of the buffer and add nodes
static inline int confirm_seq(size_t startidx, bool allow_extend,
                              GraphWalker *wlk, RepeatWalker *rpt,
                              dBNodeBuffer *nbuf, size_t colour,
                              const dBGraph *db_graph)
{
  ctx_assert(startidx < nbuf->len);
  size_t i, init_len = nbuf->len;

  graph_walker_setup(wlk, true, colour, colour, db_graph);
  graph_walker_start(wlk, nbuf->b[startidx]);

  for(i = startidx+1; graph_walker_next(wlk); i++) {
    if(!rpt_walker_attempt_traverse(rpt, wlk)) {
      reset(wlk,rpt,nbuf);
      return CONFIRM_REPEAT;
    }
    if(i < init_len) {
      if(!db_nodes_are_equal(nbuf->b[i], wlk->node)) {
        reset(wlk,rpt,nbuf);
        return CONFIRM_WRONG;
      }
    }
    else {
      db_node_buf_add(nbuf, wlk->node);
      if(!allow_extend) {
        reset(wlk,rpt,nbuf);
        nbuf->len--; // Remove node we added
        return CONFIRM_OVERSHOT;
      }
    }
  }

  // printf("stopped %zu / %zu %zu\n", i, init_len, nbuf->len);

  reset(wlk,rpt,nbuf);
  return i < init_len ? CONFIRM_SHORT : CONFIRM_SUCCESS;
}
Beispiel #3
0
static inline
int test_statement_node(dBNode node, ExpABCWorker *wrkr)
{
  const dBGraph *db_graph = wrkr->db_graph;
  dBNodeBuffer *nbuf = &wrkr->nbuf;
  GraphWalker *wlk = &wrkr->gwlk;
  RepeatWalker *rpt = &wrkr->rptwlk;
  size_t b_idx, col = wrkr->colour;

  // rpt_walker_clear(rpt);

  db_node_buf_reset(nbuf);
  db_node_buf_add(nbuf, node);

  // size_t AB_limit = wrkr->prime_AB ? SIZE_MAX : wrkr->max_AB_dist;
  size_t walk_limit = wrkr->max_AB_dist;
  // status("walk_limit: %zu", walk_limit);

  // Walk from B to find A
  graph_walker_setup(wlk, true, col, col, db_graph);
  graph_walker_start(wlk, nbuf->b[0]);

  while(graph_walker_next(wlk) && nbuf->len < walk_limit) {
    if(!rpt_walker_attempt_traverse(rpt, wlk)) {
      reset(wlk,rpt,nbuf); return RES_LOST_IN_RPT;
    }
    db_node_buf_add(nbuf, wlk->node);
  }

  reset(wlk,rpt,nbuf);

  if(nbuf->len == 1) return RES_NO_TRAVERSAL;

  // Traverse A->B
  db_nodes_reverse_complement(nbuf->b, nbuf->len);
  b_idx = nbuf->len - 1;

  if(wrkr->prime_AB)
  {
    // Prime A->B without attempting to cross
    graph_walker_prime(wlk, nbuf->b, nbuf->len, nbuf->len, true);

    while(graph_walker_next(wlk)) {
      if(!rpt_walker_attempt_traverse(rpt, wlk)) {
        reset(wlk,rpt,nbuf); return RES_LOST_IN_RPT;
      }
      db_node_buf_add(nbuf, wlk->node);
    }
  }
  else
  {
    // Attempt to traverse A->B then extend past B
    int r = confirm_seq(0, true, wlk, rpt, nbuf, col, db_graph);
    switch(r) {
      case CONFIRM_REPEAT: return RES_LOST_IN_RPT;
      case CONFIRM_OVERSHOT: ctx_assert2(0,"Can't 'overshoot' when extending");
      case CONFIRM_WRONG: return RES_AB_WRONG;
      case CONFIRM_SHORT:
        if(wrkr->print_failed_contigs)
          print_failed(node, nbuf, db_graph, true, wrkr->prime_AB);
        wrkr->ab_fail_state[wlk->last_step.status]++;
        return RES_AB_FAILED;
    }
  }

  reset(wlk,rpt,nbuf);

  if(nbuf->len == b_idx+1) return RES_NO_TRAVERSAL; // Couldn't get past B

  // Last node is now C
  // Walk from B... record whether or not we reach C
  ctx_assert(db_nodes_are_equal(nbuf->b[b_idx], db_node_reverse(node)));

  int r = confirm_seq(b_idx, false, wlk, rpt, nbuf, col, db_graph);
  switch(r) {
    case CONFIRM_REPEAT: return RES_LOST_IN_RPT;
    case CONFIRM_OVERSHOT: return RES_BC_OVERSHOT;
    case CONFIRM_WRONG: return RES_BC_WRONG;
    case CONFIRM_SHORT:
      if(wrkr->print_failed_contigs)
        print_failed(node, nbuf, db_graph, false, wrkr->prime_AB);
      wrkr->bc_fail_state[wlk->last_step.status]++;
      return RES_BC_FAILED;
    case CONFIRM_SUCCESS: return RES_ABC_SUCCESS;
  }

  die("Shouldn't reach here: r=%i", r);
  return -1;
}