/* * The main contig_extend interface. * * Returns 0 on success * -1 on failure */ int contig_extend(GapIO *io, tg_rec *contig, int ncontigs, int min_depth, int match_score, int mismatch_score) { int i, err = 0; for (i = 0; i < ncontigs; i++) { /* Left end */ UpdateTextOutput(); complement_contig(io, contig[i]); err |= contig_extend_single(io, contig[i], 1, min_depth, match_score, mismatch_score); /* Right end */ UpdateTextOutput(); complement_contig(io, contig[i]); err |= contig_extend_single(io, contig[i], 0, min_depth, match_score, mismatch_score); } return err ? -1 : 0; }
/* * Match callback. * 'obj' is a match contained within the 'repeat' list. */ void *repeat_obj_func(int job, void *jdata, obj_match *obj, mobj_repeat *repeat) { static char buf[80]; obj_cs *cs; int cs_id; cs_id = type_to_result(repeat->io, REG_TYPE_CONTIGSEL, 0); cs = result_data(repeat->io, cs_id, 0); switch(job) { case OBJ_LIST_OPERATIONS: if (io_rdonly(repeat->io) && ((obj->c1 > 0 && obj->c2 < 0) || (obj->c1 < 0 && obj->c2 > 0))) { return "Information\0Hide\0IGNORE\0" "IGNORE\0SEPARATOR\0Remove\0"; } else { return "Information\0Hide\0Invoke join editor *\0" "Invoke contig editors\0SEPARATOR\0Remove\0"; } case OBJ_INVOKE_OPERATION: switch(*((int *)jdata)) { case 0: /* Information */ vfuncgroup(1, "2D plot matches"); case -1: /* Information from results manager */ start_message(); vmessage("Repeat match (%s)\n", ((obj->c1 > 0) == (obj->c2 > 0)) ? "direct" : "inverted"); vmessage(" From contig %s(#%d) at %d\n", get_contig_name(repeat->io, ABS(obj->c1)), io_clnbr(repeat->io, ABS(obj->c1)), obj->pos1); vmessage(" With contig %s(#%d) at %d\n", get_contig_name(repeat->io, ABS(obj->c2)), io_clnbr(repeat->io, ABS(obj->c2)), obj->pos2); vmessage(" Length %d\n\n", obj->length); end_message(cs->window); break; case 1: /* Hide */ obj_hide(GetInterp(), cs->window, obj, (mobj_repeat *)repeat, csplot_hash); break; case -2: /* default */ case 2: /* Invoke join editor */ { int cnum[2], llino[2], pos[2]; obj->flags |= OBJ_FLAG_VISITED; repeat->current = obj - repeat->match; Tcl_VarEval(GetInterp(), "CSLastUsed ", CPtr2Tcl(repeat), NULL); cnum[0] = ABS(obj->c1); cnum[1] = ABS(obj->c2); /* Complement a contig if needed */ if ((obj->c1 > 0) != (obj->c2 > 0)) { if (cnum[0] == cnum[1]) { verror(ERR_WARN, "join_editor", "cannot display the same contig in two " "different orientations"); break; } if (io_rdonly(repeat->io)) { bell(); break; } if (io_clength(repeat->io, ABS(obj->c1)) < io_clength(repeat->io, ABS(obj->c2))) { if (-1 == complement_contig(repeat->io, ABS(obj->c1))) if (-1 == complement_contig(repeat->io, ABS(obj->c2))) return NULL; } else { if (-1 == complement_contig(repeat->io, ABS(obj->c2))) if (-1 == complement_contig(repeat->io, ABS(obj->c1))) return NULL; } } /* * NB: obj->pos1 now may not be the same value as when this * function was entered, due to the complementing! */ pos[0] = obj->pos1; pos[1] = obj->pos2; llino[0] = io_clnbr(repeat->io, cnum[0]); llino[1] = io_clnbr(repeat->io, cnum[1]); join_contig(GetInterp(), repeat->io, cnum, llino, pos, consensus_cutoff, quality_cutoff); break; } case 3: /* Invoke contig editors */ { int cnum, llino, pos; cnum = ABS(obj->c1); llino = io_clnbr(repeat->io, cnum); pos = obj->pos1; edit_contig(GetInterp(), repeat->io, cnum, llino, pos, consensus_cutoff, quality_cutoff, 0, NULL); cnum = ABS(obj->c2); llino = io_clnbr(repeat->io, cnum); pos = obj->pos2; edit_contig(GetInterp(), repeat->io, cnum, llino, pos, consensus_cutoff, quality_cutoff, 0, NULL); break; } case 4: /* Remove */ obj_remove(GetInterp(), cs->window, obj, (mobj_repeat *)repeat, csplot_hash); break; } break; case OBJ_GET_BRIEF: sprintf(buf, "Repeat: %c#%d@%d with %c#%d@%d, len %d", obj->c1 > 0 ? '+' : '-', io_clnbr(repeat->io, ABS(obj->c1)), obj->pos1, obj->c2 > 0 ? '+' : '-', io_clnbr(repeat->io, ABS(obj->c2)), obj->pos2, obj->length); return buf; } return NULL; }
/* * Complements a scaffold; both complementing each contig within it and * reversing the order of contigs in the scaffold. * * Returns 0 on success * -1 on failure */ int complement_scaffold(GapIO *io, tg_rec srec) { scaffold_t *f; int i, j, nc = ArrayMax(io->contig_order); scaffold_member_t *contigs; tg_rec *crecs; HashTable *h; reg_order ro; reg_buffer_start rs; reg_buffer_end re; if (!(f = cache_search(io, GT_Scaffold, srec))) return -1; if (!(f = cache_rw(io, f))) return -1; cache_incr(io, f); /* Complement contigs */ contigs = ArrayBase(scaffold_member_t, f->contig); for (i = 0; i < ArrayMax(f->contig); i++) { complement_contig(io, contigs[i].rec); } /* Reverse the order of the contigs in the scaffold array */ for (i = 0, j = ArrayMax(f->contig)-1; i < j; i++, j--) { scaffold_member_t cr1 = contigs[i]; contigs[i] = contigs[j]; contigs[j] = cr1; } /* * Reverse the order of contigs in the contig_order array too. * This is the part that really matters. It's also hard as the contigs * in the contig order array could be in any order and not adjacent. * For our purposes we'll just ensure the contigs in this scaffold in * the contig order array match our freshly complemented scaffold * ordering. * * We initially build a hash table of contigs in this scaffold, and * then iterate through contig_order copying out the new contigs whenever * one matches. */ h = HashTableCreate(nc, 0); for (i = 0; i < ArrayMax(f->contig); i++) { HashData hd; hd.i = 0; HashTableAdd(h, (char *)&contigs[i].rec, sizeof(tg_rec), hd, NULL); } /* Replace any contig matching the scaffold with the new order */ crecs = ArrayBase(tg_rec, io->contig_order); for (i = j = 0; i < nc; i++) { HashItem *hi; if (!(hi = HashTableSearch(h, (char *)&crecs[i], sizeof(tg_rec)))) continue; crecs[i] = contigs[j++].rec; } /* Send event messages around */ rs.job = REG_BUFFER_START; for (i = 0; i < nc; i++) { HashItem *hi; if (!(hi = HashTableSearch(h, (char *)&crecs[i], sizeof(tg_rec)))) continue; contig_notify(io, crecs[i], (reg_data *)&rs); } ro.job = REG_ORDER; for (i = 0; i < nc; i++) { HashItem *hi; if (!(hi = HashTableSearch(h, (char *)&crecs[i], sizeof(tg_rec)))) continue; ro.pos = i+1; contig_notify(io, crecs[i], (reg_data *)&ro); } /* Notify the end of our updates */ re.job = REG_BUFFER_END; for (i = 0; i < nc; i++) { HashItem *hi; if (!(hi = HashTableSearch(h, (char *)&crecs[i], sizeof(tg_rec)))) continue; contig_notify(io, crecs[i], (reg_data *)&re); } HashTableDestroy(h, 0); cache_decr(io, f); return 0; }
/* * functions to act upon matches generated using TAGs */ void *find_oligo_obj_func1(int job, void *jdata, obj_match *obj, mobj_find_oligo *find_oligo) { static char buf[80]; obj_cs *cs; int cs_id; cs_id = type_to_result(find_oligo->io, REG_TYPE_CONTIGSEL, 0); cs = result_data(find_oligo->io, cs_id); switch(job) { case OBJ_LIST_OPERATIONS: return "Information\0Hide\0Invoke join editor *\0" "Invoke contig editors\0SEPARATOR\0Remove\0"; case OBJ_INVOKE_OPERATION: switch(*((int *)jdata)) { case 0: /* Information */ vfuncgroup(1, "2D plot matches"); case -1: /* Information from results manager */ start_message(); vmessage("Sequence search:\n"); vmessage(" From contig %s(#%"PRIrec") at %d\n", get_contig_name(find_oligo->io, ABS(obj->c1)), io_clnbr(find_oligo->io, ABS(obj->c1)), obj->pos1); vmessage(" With contig %s(#%"PRIrec") at %d\n", get_contig_name(find_oligo->io, ABS(obj->c2)), io_clnbr(find_oligo->io, ABS(obj->c2)), obj->pos2); vmessage(" Length %d, match %2.2f%%\n\n", obj->length, (float)obj->score / obj->length * 100.0 ); end_message(cs->window); break; case 1: /* Hide */ obj_hide(GetInterp(), cs->window, obj, (mobj_find_oligo *)find_oligo, csplot_hash); break; case -2: /* default */ case 2: /* Invoke join editor */ { tg_rec cnum[2], llino[2]; int pos[2]; obj->flags |= OBJ_FLAG_VISITED; find_oligo->current = obj - find_oligo->match; Tcl_VarEval(GetInterp(), "CSLastUsed ", CPtr2Tcl(find_oligo), NULL); cnum[0] = ABS(obj->c1); cnum[1] = ABS(obj->c2); /* Complement a contig if needed */ if ((obj->c1 > 0) != (obj->c2 > 0)) { if (cnum[0] == cnum[1]) { verror(ERR_WARN, "join_editor", "cannot display the same contig in two " "different orientations"); break; } if (find_oligo->io->read_only) { bell(); break; } if (io_clength(find_oligo->io, ABS(obj->c1)) < io_clength(find_oligo->io, ABS(obj->c2))) { if (-1 == complement_contig(find_oligo->io, ABS(obj->c1))) if (-1 == complement_contig(find_oligo->io, ABS(obj->c2))) return NULL; } else { if (-1 == complement_contig(find_oligo->io, ABS(obj->c2))) if (-1 == complement_contig(find_oligo->io, ABS(obj->c1))) return NULL; } } /* * NB: obj->pos1 now may not be the same value as when this * function was entered, due to the complementing! */ pos[0] = obj->pos1; pos[1] = obj->pos2; llino[0] = io_clnbr(find_oligo->io, cnum[0]); llino[1] = io_clnbr(find_oligo->io, cnum[1]); join_contig(find_oligo->io, cnum, llino, pos); break; } case 3: /* Invoke contig editors */ { tg_rec cnum, llino; int pos; cnum = ABS(obj->c1); llino = io_clnbr(find_oligo->io, cnum); pos = obj->pos1; edit_contig(find_oligo->io, cnum, llino, pos); cnum = ABS(obj->c2); llino = io_clnbr(find_oligo->io, cnum); pos = obj->pos2; edit_contig(find_oligo->io, cnum, llino, pos); break; } case 4: /* Remove */ obj_remove(GetInterp(), cs->window, obj, (mobj_find_oligo *)find_oligo, csplot_hash); break; } break; case OBJ_GET_BRIEF: sprintf(buf, "Oligo: %c#%"PRIrec"@%d with %c#%"PRIrec"@%d, " "len %d, match %2.2f%%", obj->c1 > 0 ? '+' : '-', io_clnbr(find_oligo->io, ABS(obj->c1)), obj->pos1, obj->c2 > 0 ? '+' : '-', io_clnbr(find_oligo->io, ABS(obj->c2)), obj->pos2, obj->length, (float)obj->score / obj->length * 100.0); return buf; } return NULL; }