// creat Chan's hull void shape_build_hull(shape_t* shape) { assert(shape!= NULL); points_v hull; kv_init(hull); kv_copy(point_t, hull, shape->points); uint32_t s = chanhull(hull.a, hull.n); uint32_t l = hull.n-s; // copy part of points vector kv_resize(point_t, shape->hull, l+1); shape->hull.n = l+1; // memcpy(shape->hull.a, hull.a+s, sizeof(point_t)*l); // shape->hull.a[l] = *(hull.a+s); // revert point direction for(uint32_t i=0; i<=l;i++) { shape->hull.a[l-i] = hull.a[s+i%l]; } kv_destroy(hull); }
static aln_v align_read(const kseq_t *read, const kseq_v targets, const align_config_t *conf) { kseq_t *r; const int32_t read_len = read->seq.l; aln_v result; kv_init(result); kv_resize(aln_t, result, kv_size(targets)); uint8_t *read_num = calloc(read_len, sizeof(uint8_t)); for(size_t k = 0; k < read_len; ++k) read_num[k] = conf->table[(int)read->seq.s[k]]; // Align to each target kswq_t *qry = NULL; for(size_t j = 0; j < kv_size(targets); j++) { // Encode target r = &kv_A(targets, j); uint8_t *ref_num = calloc(r->seq.l, sizeof(uint8_t)); for(size_t k = 0; k < r->seq.l; ++k) ref_num[k] = conf->table[(int)r->seq.s[k]]; aln_t aln; aln.target_idx = j; aln.loc = ksw_align(read_len, read_num, r->seq.l, ref_num, conf->m, conf->mat, conf->gap_o, conf->gap_e, KSW_XSTART, &qry); ksw_global(aln.loc.qe - aln.loc.qb + 1, &read_num[aln.loc.qb], aln.loc.te - aln.loc.tb + 1, &ref_num[aln.loc.tb], conf->m, conf->mat, conf->gap_o, conf->gap_e, 50, /* TODO: Magic number - band width */ &aln.n_cigar, &aln.cigar); aln.nm = 0; size_t qi = aln.loc.qb, ri = aln.loc.tb; for(size_t k = 0; k < aln.n_cigar; k++) { const int32_t oplen = bam_cigar_oplen(aln.cigar[k]), optype = bam_cigar_type(aln.cigar[k]); if(optype & 3) { // consumes both - check for mismatches for(size_t j = 0; j < oplen; j++) { if(UNLIKELY(read_num[qi + j] != ref_num[ri + j])) aln.nm++; } } else { aln.nm += oplen; } if(optype & 1) qi += oplen; if(optype & 2) ri += oplen; } kv_push(aln_t, result, aln); free(ref_num); } free(qry); free(read_num); ks_introsort(dec_score, kv_size(result), result.a); return result; }
static aln_v align_read(const kseq_t *read, const kseq_v targets, const size_t n_extra_targets, const kseq_v *extra_targets, const align_config_t *conf) { kseq_t *r; const int32_t read_len = read->seq.l; aln_v result; kv_init(result); kv_resize(aln_t, result, kv_size(targets)); uint8_t *read_num = calloc(read_len, sizeof(uint8_t)); for (int k = 0; k < read_len; ++k) read_num[k] = conf->table[(int)read->seq.s[k]]; // Align to each target kswq_t *qry = NULL; int min_score = -1000; int max_score = 0; for (size_t j = 0; j < kv_size(targets); j++) { // Encode target r = &kv_A(targets, j); aln_t aln = align_read_against_one(r, read_len, read_num, &qry, conf, min_score); if (aln.cigar != NULL) { max_score = aln.loc.score > max_score ? aln.loc.score : max_score; min_score = (aln.loc.score - conf->max_drop) > min_score ? (aln.loc.score - conf->max_drop) : min_score; kv_push(aln_t, result, aln); } } /* If no alignments to the first set of targets reached the minimum score, * abort. */ if (max_score < conf->min_score) { // kv_size returns the n field of a kvec_t, which is a size_t. for (size_t i = 0; i < kv_size(result); i++) free(kv_A(result, i).cigar); kv_size(result) = 0; free(qry); free(read_num); return result; } drop_low_scores(&result, 0, conf->max_drop); // Extra references - qe points to the exact end of the sequence int qend = kv_A(result, 0).loc.qe + 1; int read_len_trunc = read_len - qend; uint8_t *read_num_trunc = read_num + qend; free(qry); qry = NULL; if (read_len_trunc > 2) { for (size_t i = 0; i < n_extra_targets; i++) { const size_t idx = n_extra_targets - i - 1; min_score = -1000; const size_t init_count = kv_size(result); for (size_t j = 0; j < kv_size(extra_targets[idx]); j++) { r = &kv_A(extra_targets[idx], j); aln_t aln = align_read_against_one(r, read_len_trunc, read_num_trunc, &qry, conf, min_score); if (aln.cigar != NULL) { min_score = (aln.loc.score - conf->max_drop) > min_score ? (aln.loc.score - conf->max_drop) : min_score; aln.loc.qb += qend; aln.loc.qe += qend; kv_push(aln_t, result, aln); } } drop_low_scores(&result, init_count, conf->max_drop); /* Truncate */ const int alen = kv_A(result, init_count).loc.qe - kv_A(result, init_count).loc.qb; read_len_trunc = read_len_trunc - alen; free(qry); qry = NULL; } } free(qry); free(read_num); return result; }