// get the 3 genotype likelihoods static double *get_pdg3(const bcf1_t *b) { double *pdg; const uint8_t *PL = 0; int i, PL_len = 0; // initialize g_q2p if necessary if (g_q2p[0] == 0.) for (i = 0; i < 256; ++i) g_q2p[i] = pow(10., -i / 10.); // set PL and PL_len for (i = 0; i < b->n_gi; ++i) { if (b->gi[i].fmt == bcf_str2int("PL", 2)) { PL = (const uint8_t*)b->gi[i].data; PL_len = b->gi[i].len; break; } } if (i == b->n_gi) return 0; // no PL // fill pdg pdg = malloc(3 * b->n_smpl * sizeof(double)); for (i = 0; i < b->n_smpl; ++i) { const uint8_t *pi = PL + i * PL_len; double *p = pdg + i * 3; p[0] = g_q2p[pi[2]]; p[1] = g_q2p[pi[1]]; p[2] = g_q2p[pi[0]]; } return pdg; }
int bcf_2qcall(bcf_hdr_t *h, bcf1_t *b) { int a[4], k, g[10], l, map[4], k1, j, i, i0, anno[16], dp, mq, d_rest; char *s; if (b->ref[1] != 0 || b->n_alleles > 4) return -1; // ref is not a single base for (i = 0; i < b->n_gi; ++i) if (b->gi[i].fmt == bcf_str2int("PL", 2)) break; if (i == b->n_gi) return -1; // no PL if (read_I16(b, anno) != 0) return -1; // no I16; FIXME: can be improved d_rest = dp = anno[0] + anno[1] + anno[2] + anno[3]; if (dp == 0) return -1; // depth is zero mq = (int)(sqrt((double)(anno[9] + anno[11]) / dp) + .499); i0 = i; a[0] = nt4_table[(int)b->ref[0]]; if (a[0] > 3) return -1; // ref is not A/C/G/T a[1] = a[2] = a[3] = -2; // -1 has a special meaning if (b->alt[0] == 0) return -1; // no alternate allele map[0] = map[1] = map[2] = map[3] = -2; map[a[0]] = 0; for (k = 0, s = b->alt, k1 = -1; k < 3 && *s; ++k, s += 2) { if (s[1] != ',' && s[1] != 0) return -1; // ALT is not single base a[k+1] = nt4_table[(int)*s]; if (a[k+1] >= 0) map[a[k+1]] = k+1; else k1 = k+1; if (s[1] == 0) break; } for (k = 0; k < 4; ++k) if (map[k] < 0) map[k] = k1; for (i = 0; i < h->n_smpl; ++i) { int d; uint8_t *p = (uint8_t*)b->gi[i0].data + i * b->gi[i0].len; //dong code, verify for (j = 0; j < b->gi[i0].len; ++j) if (p[j]) break; d = (int)((double)d_rest / (h->n_smpl - i) + .499); if (d == 0) d = 1; if (j == b->gi[i0].len) d = 0; d_rest -= d; for (k = j = 0; k < 4; ++k) { for (l = k; l < 4; ++l) { int t, x = map[k], y = map[l]; if (x > y) t = x, x = y, y = t; // swap g[j++] = p[y * (y+1) / 2 + x]; } } printf("%s\t%d\t%c", h->ns[b->tid], b->pos+1, *b->ref); printf("\t%d\t%d\t0", d, mq); for (j = 0; j < 10; ++j) printf("\t%d", g[j]); printf("\t%s\n", h->sns[i]); } return 0; }
int bcf_p1_cal(bcf1_t *b, bcf_p1aux_t *ma, bcf_p1rst_t *rst) { int i, k; long double sum = 0.; // set PL and PL_len for (i = 0; i < b->n_gi; ++i) { if (b->gi[i].fmt == bcf_str2int("PL", 2)) { ma->PL = (uint8_t*)b->gi[i].data; ma->PL_len = b->gi[i].len; break; } } if (b->n_alleles < 2) return -1; // FIXME: find a better solution // rst->rank0 = cal_pdg(b, ma); rst->f_exp = mc_cal_afs(ma); rst->p_ref = ma->afs1[ma->M]; // calculate f_flat and f_em for (k = 0, sum = 0.; k <= ma->M; ++k) sum += (long double)ma->z[k]; rst->f_flat = 0.; for (k = 0; k <= ma->M; ++k) { double p = ma->z[k] / sum; rst->f_flat += k * p; } rst->f_flat /= ma->M; { // calculate f_em double flast = rst->f_flat; for (i = 0; i < MC_MAX_EM_ITER; ++i) { rst->f_em = mc_freq_iter(flast, ma); if (fabs(rst->f_em - flast) < MC_EM_EPS) break; flast = rst->f_em; } } rst->g[0] = rst->g[1] = rst->g[2] = -1.; contrast(ma, rst->pc); return 0; }
int bcf_p1_cal(const bcf1_t *b, int do_contrast, bcf_p1aux_t *ma, bcf_p1rst_t *rst) { int i, k; long double sum = 0.; ma->is_indel = bcf_is_indel(b); rst->perm_rank = -1; // set PL and PL_len for (i = 0; i < b->n_gi; ++i) { if (b->gi[i].fmt == bcf_str2int("PL", 2)) { ma->PL = (uint8_t*)b->gi[i].data; ma->PL_len = b->gi[i].len; break; } } if (i == b->n_gi) return -1; // no PL if (b->n_alleles < 2) return -1; // FIXME: find a better solution // rst->rank0 = cal_pdg(b, ma); rst->f_exp = mc_cal_afs(ma, &rst->p_ref_folded, &rst->p_var_folded); rst->p_ref = ma->afs1[ma->M]; for (k = 0, sum = 0.; k < ma->M; ++k) sum += ma->afs1[k]; rst->p_var = (double)sum; { // compute the allele count double max = -1; rst->ac = -1; for (k = 0; k <= ma->M; ++k) if (max < ma->z[k]) max = ma->z[k], rst->ac = k; rst->ac = ma->M - rst->ac; } // calculate f_flat and f_em for (k = 0, sum = 0.; k <= ma->M; ++k) sum += (long double)ma->z[k]; rst->f_flat = 0.; for (k = 0; k <= ma->M; ++k) { double p = ma->z[k] / sum; rst->f_flat += k * p; } rst->f_flat /= ma->M; { // estimate equal-tail credible interval (95% level) int l, h; double p; for (i = 0, p = 0.; i <= ma->M; ++i) if (p + ma->afs1[i] > 0.025) break; else p += ma->afs1[i]; l = i; for (i = ma->M, p = 0.; i >= 0; --i) if (p + ma->afs1[i] > 0.025) break; else p += ma->afs1[i]; h = i; rst->cil = (double)(ma->M - h) / ma->M; rst->cih = (double)(ma->M - l) / ma->M; } if (ma->n1 > 0) { // compute LRT double max0, max1, max2; for (k = 0, max0 = -1; k <= ma->M; ++k) if (max0 < ma->z[k]) max0 = ma->z[k]; for (k = 0, max1 = -1; k <= ma->n1 * 2; ++k) if (max1 < ma->z1[k]) max1 = ma->z1[k]; for (k = 0, max2 = -1; k <= ma->M - ma->n1 * 2; ++k) if (max2 < ma->z2[k]) max2 = ma->z2[k]; rst->lrt = log(max1 * max2 / max0); rst->lrt = rst->lrt < 0? 1 : kf_gammaq(.5, rst->lrt); } else rst->lrt = -1.0; rst->cmp[0] = rst->cmp[1] = rst->cmp[2] = rst->p_chi2 = -1.0; if (do_contrast && rst->p_var > 0.5) // skip contrast2() if the locus is a strong non-variant rst->p_chi2 = contrast2(ma, rst->cmp); return 0; }
int vcf_read(bcf_t *bp, bcf_hdr_t *h, bcf1_t *b) { int dret, k, i, sync = 0; vcf_t *v = (vcf_t*)bp->v; char *p, *q; kstring_t str, rn; ks_tokaux_t aux, a2; if (!bp->is_vcf) return bcf_read(bp, h, b); v->line.l = 0; str.l = 0; str.m = b->m_str; str.s = b->str; rn.l = rn.m = h->l_nm; rn.s = h->name; if (ks_getuntil(v->ks, '\n', &v->line, &dret) < 0) return -1; b->n_smpl = h->n_smpl; for (p = kstrtok(v->line.s, "\t", &aux), k = 0; p; p = kstrtok(0, 0, &aux), ++k) { *(char*)aux.p = 0; if (k == 0) { // ref int tid = bcf_str2id(v->refhash, p); if (tid < 0) { tid = bcf_str2id_add(v->refhash, strdup(p)); kputs(p, &rn); kputc('\0', &rn); sync = 1; } b->tid = tid; } else if (k == 1) { // pos b->pos = atoi(p) - 1; } else if (k == 5) { // qual b->qual = (p[0] >= '0' && p[0] <= '9')? atof(p) : 0; } else if (k <= 8) { // variable length strings kputs(p, &str); kputc('\0', &str); b->l_str = str.l; b->m_str = str.m; b->str = str.s; if (k == 8) bcf_sync(b); } else { // k > 9 if (strncmp(p, "./.", 3) == 0) { for (i = 0; i < b->n_gi; ++i) { if (b->gi[i].fmt == bcf_str2int("GT", 2)) { ((uint8_t*)b->gi[i].data)[k-9] = 1<<7; } else if (b->gi[i].fmt == bcf_str2int("GQ", 2)) { ((uint8_t*)b->gi[i].data)[k-9] = 0; } else if (b->gi[i].fmt == bcf_str2int("SP", 2)) { ((int32_t*)b->gi[i].data)[k-9] = 0; } else if (b->gi[i].fmt == bcf_str2int("DP", 2)) { ((uint16_t*)b->gi[i].data)[k-9] = 0; } else if (b->gi[i].fmt == bcf_str2int("PL", 2)) { int y = b->n_alleles * (b->n_alleles + 1) / 2; memset((uint8_t*)b->gi[i].data + (k - 9) * y, 0, y); } else if (b->gi[i].fmt == bcf_str2int("GL", 2)) { int y = b->n_alleles * (b->n_alleles + 1) / 2; memset((float*)b->gi[i].data + (k - 9) * y, 0, y * 4); } } goto endblock; } for (q = kstrtok(p, ":", &a2), i = 0; q && i < b->n_gi; q = kstrtok(0, 0, &a2), ++i) { if (b->gi[i].fmt == bcf_str2int("GT", 2)) { ((uint8_t*)b->gi[i].data)[k-9] = (q[0] - '0')<<3 | (q[2] - '0') | (q[1] == '/'? 0 : 1) << 6; } else if (b->gi[i].fmt == bcf_str2int("GQ", 2)) { double _x = strtod(q, &q); int x = (int)(_x + .499); if (x > 255) x = 255; ((uint8_t*)b->gi[i].data)[k-9] = x; } else if (b->gi[i].fmt == bcf_str2int("SP", 2)) { int x = strtol(q, &q, 10); if (x > 0xffff) x = 0xffff; ((uint32_t*)b->gi[i].data)[k-9] = x; } else if (b->gi[i].fmt == bcf_str2int("DP", 2)) { int x = strtol(q, &q, 10); if (x > 0xffff) x = 0xffff; ((uint16_t*)b->gi[i].data)[k-9] = x; } else if (b->gi[i].fmt == bcf_str2int("PL", 2)) { int x, y, j; uint8_t *data = (uint8_t*)b->gi[i].data; y = b->n_alleles * (b->n_alleles + 1) / 2; for (j = 0; j < y; ++j) { x = strtol(q, &q, 10); if (x > 255) x = 255; data[(k-9) * y + j] = x; ++q; } } else if (b->gi[i].fmt == bcf_str2int("GL", 2)) { int j, y; float x, *data = (float*)b->gi[i].data; y = b->n_alleles * (b->n_alleles + 1) / 2; for (j = 0; j < y; ++j) { x = strtod(q, &q); data[(k-9) * y + j] = x > 0? -x/10. : x; ++q; } } } endblock: i = i; } } h->l_nm = rn.l; h->name = rn.s; if (sync) bcf_hdr_sync(h); return v->line.l + 1; }