X-Git-Url: https://git.donarmstrong.com/?p=samtools.git;a=blobdiff_plain;f=bcftools%2Fprob1.c;h=e3d6b5eb42fee41bb3b2e8f392b5ae38d1934bc5;hp=2a9c0369f480fb3692d3f6edb693f7f0f8b74436;hb=da45f88bac09817fcd87916d3e104f0e4bc53874;hpb=ec294adf095b60c90e57e31f3af1335138c5a22a diff --git a/bcftools/prob1.c b/bcftools/prob1.c index 2a9c036..e3d6b5e 100644 --- a/bcftools/prob1.c +++ b/bcftools/prob1.c @@ -201,6 +201,7 @@ void bcf_p1_destroy(bcf_p1aux_t *ma) } extern double kf_gammap(double s, double z); +int test16(bcf1_t *b, anno16_t *a); int call_multiallelic_gt(bcf1_t *b, bcf_p1aux_t *ma, double threshold) { @@ -215,9 +216,14 @@ int call_multiallelic_gt(bcf1_t *b, bcf_p1aux_t *ma, double threshold) if ( nals==1 ) return 1; - if ( nals>4 ) { fprintf(stderr,"too many alts: %d\n", nals); exit(1); } + if ( nals>4 ) + { + if ( *b->ref=='N' ) return 0; + fprintf(stderr,"Not ready for this, more than 4 alleles at %d: %s, %s\n", b->pos+1, b->ref,b->alt); + exit(1); + } - // set PL and PL_len + // find PL and DP FORMAT indexes uint8_t *pl = NULL; int npl = 0, idp=-1; int i; @@ -232,16 +238,20 @@ int call_multiallelic_gt(bcf1_t *b, bcf_p1aux_t *ma, double threshold) } if ( !pl ) return -1; + assert(ma->q2p[0] == 1); + + // Init P(D|G) int npdg = nals*(nals+1)/2; - float *pdg,*_pdg; - _pdg = pdg = malloc(sizeof(float)*ma->n*npdg); + double *pdg,*_pdg; + _pdg = pdg = malloc(sizeof(double)*ma->n*npdg); for (i=0; in; i++) { int j; - float sum = 0; + double sum = 0; for (j=0; jq2p[pl[j]]; sum += _pdg[j]; } if ( sum ) @@ -251,88 +261,94 @@ int call_multiallelic_gt(bcf1_t *b, bcf_p1aux_t *ma, double threshold) } if ((p = strstr(b->info, "QS=")) == 0) { fprintf(stderr,"INFO/QS is required with -m, exiting\n"); exit(1); } - float qsum[4]; - if ( sscanf(p+3,"%f,%f,%f,%f",&qsum[0],&qsum[1],&qsum[2],&qsum[3])!=4 ) { fprintf(stderr,"Could not parse %s\n",p); exit(1); } + double qsum[4]; + if ( sscanf(p+3,"%lf,%lf,%lf,%lf",&qsum[0],&qsum[1],&qsum[2],&qsum[3])!=4 ) { fprintf(stderr,"Could not parse %s\n",p); exit(1); } - + + // Calculate the most likely combination of alleles int ia,ib,ic, max_als=0, max_als2=0; - float max_lk = INT_MIN, max_lk2 = INT_MIN, lk_sum = INT_MIN; + double ref_lk = 0, max_lk = INT_MIN, max_lk2 = INT_MIN, lk_sum = INT_MIN; for (ia=0; ian; isample++) { - float *p = pdg + isample*npdg; - assert( log(p[iaa]) <= 0 ); + double *p = pdg + isample*npdg; + // assert( log(p[iaa]) <= 0 ); lk_tot += log(p[iaa]); } + if ( ia==0 ) ref_lk = lk_tot; if ( max_lklk_sum ? lk_tot + log(1+exp(lk_sum-lk_tot)) : lk_sum + log(1+exp(lk_tot-lk_sum)); } - for (ia=0; ia1 ) { - if ( qsum[ia]==0 ) continue; - //if ( ia && qsum[ia]==0 ) continue; - for (ib=0; ibn; isample++) + if ( qsum[ia]==0 ) continue; + int iaa = (ia+1)*(ia+2)/2-1; + for (ib=0; ibploidy && b->ploidy[isample]==1 ) continue; - float *p = pdg + isample*npdg; - assert( log(fa*p[iaa] + fb*p[ibb] + fab*p[iab]) <= 0 ); - lk_tot += log(fa*p[iaa] + fb*p[ibb] + fab*p[iab]); + if ( qsum[ib]==0 ) continue; + double lk_tot = 0; + double fa = qsum[ia]/(qsum[ia]+qsum[ib]); + double fb = qsum[ib]/(qsum[ia]+qsum[ib]); + double fab = 2*fa*fb; fa *= fa; fb *= fb; + int isample, ibb = (ib+1)*(ib+2)/2-1, iab = iaa - ia + ib; + for (isample=0; isamplen; isample++) + { + if ( b->ploidy && b->ploidy[isample]==1 ) continue; + double *p = pdg + isample*npdg; + //assert( log(fa*p[iaa] + fb*p[ibb] + fab*p[iab]) <= 0 ); + lk_tot += log(fa*p[iaa] + fb*p[ibb] + fab*p[iab]); + } + if ( max_lklk_sum ? lk_tot + log(1+exp(lk_sum-lk_tot)) : lk_sum + log(1+exp(lk_tot-lk_sum)); } - if ( max_lklk_sum ? lk_tot + log(1+exp(lk_sum-lk_tot)) : lk_sum + log(1+exp(lk_tot-lk_sum)); } } - for (ia=0; ia2 ) { - if ( qsum[ia]==0 ) continue; - //if ( ia && qsum[ia]==0 ) continue; - for (ib=0; ibn; isample++) + if ( qsum[ib]==0 ) continue; + int ibb = (ib+1)*(ib+2)/2-1; + int iab = iaa - ia + ib; + for (ic=0; icploidy && b->ploidy[isample]==1 ) continue; - float *p = pdg + isample*npdg; - assert( log(fa*p[iaa] + fb*p[ibb] + fc*p[icc] + fab*p[iab] + fac*p[iac] + fbc*p[ibc]) <= 0 ); - lk_tot += log(fa*p[iaa] + fb*p[ibb] + fc*p[icc] + fab*p[iab] + fac*p[iac] + fbc*p[ibc]); + if ( qsum[ic]==0 ) continue; + double lk_tot = 0; + double fa = qsum[ia]/(qsum[ia]+qsum[ib]+qsum[ic]); + double fb = qsum[ib]/(qsum[ia]+qsum[ib]+qsum[ic]); + double fc = qsum[ic]/(qsum[ia]+qsum[ib]+qsum[ic]); + double fab = 2*fa*fb, fac = 2*fa*fc, fbc = 2*fb*fc; fa *= fa; fb *= fb; fc *= fc; + int isample, icc = (ic+1)*(ic+2)/2-1; + int iac = iaa - ia + ic, ibc = ibb - ib + ic; + for (isample=0; isamplen; isample++) + { + if ( b->ploidy && b->ploidy[isample]==1 ) continue; + double *p = pdg + isample*npdg; + //assert( log(fa*p[iaa] + fb*p[ibb] + fc*p[icc] + fab*p[iab] + fac*p[iac] + fbc*p[ibc]) <= 0 ); + lk_tot += log(fa*p[iaa] + fb*p[ibb] + fc*p[icc] + fab*p[iab] + fac*p[iac] + fbc*p[ibc]); + } + if ( max_lklk_sum ? lk_tot + log(1+exp(lk_sum-lk_tot)) : lk_sum + log(1+exp(lk_tot-lk_sum)); } - if ( max_lklk_sum ? lk_tot + log(1+exp(lk_sum-lk_tot)) : lk_sum + log(1+exp(lk_tot-lk_sum)); } } } + + // Should we add another allele, does it increase the likelihood significantly? int n1=0, n2=0; for (i=0; iref, &s); kputc('\0', &s); - kputs(b->alt, &s); kputc('\0', &s); kputc('\0', &s); - kputs(b->info, &s); if (b->info[0]) kputc(';', &s); kputc('\0', &s); - kputs(b->fmt, &s); kputc('\0', &s); - free(b->str); - b->m_str = s.m; b->l_str = s.l; b->str = s.s; - b->qual = -4.343*(log(1-exp(max_lk-lk_sum))); - if ( b->qual>999 ) b->qual = 999; - //bcf_sync(b); - - int x, old_n_gi = b->n_gi; + int old_n_gi = b->n_gi; s.m = b->m_str; s.l = b->l_str - 1; s.s = b->str; kputs(":GT:GQ", &s); kputc('\0', &s); b->m_str = s.m; b->l_str = s.l; b->str = s.s; bcf_sync(b); - // Call GT - int isample, gts=0; + // Call GTs + int isample, gts=0, ac[4] = {0,0,0,0}; for (isample = 0; isample < b->n_smpl; isample++) { int ploidy = b->ploidy ? b->ploidy[isample] : 2; - float *p = pdg + isample*npdg; + double *p = pdg + isample*npdg; int ia, als = 0; - float lk = INT_MIN, lk_sum=0; + double lk = 0, lk_sum=0; for (ia=0; ia lk ) { lk = _lk; als = ia<<3 | ia; } lk_sum += _lk; } @@ -387,7 +392,7 @@ int call_multiallelic_gt(bcf1_t *b, bcf_p1aux_t *ma, double threshold) { if ( !(max_als&1< lk ) { lk = _lk; als = ib<<3 | ia; } lk_sum += _lk; } @@ -396,17 +401,64 @@ int call_multiallelic_gt(bcf1_t *b, bcf_p1aux_t *ma, double threshold) lk = -log(1-lk/lk_sum)/0.2302585; if ( idp>=0 && ((uint16_t*)b->gi[idp].data)[isample]==0 ) { - als |= 1<<7; - lk = 0; + ((uint8_t*)b->gi[old_n_gi].data)[isample] = 1<<7; + ((uint8_t*)b->gi[old_n_gi+1].data)[isample] = 0; + continue; } - ((uint8_t*)b->gi[old_n_gi].data)[isample] = als; + ((uint8_t*)b->gi[old_n_gi].data)[isample] = als; ((uint8_t*)b->gi[old_n_gi+1].data)[isample] = lk<100 ? (int)lk : 99; - gts |= (als>>3&7) | (als&7); + gts |= 1<<(als>>3&7) | 1<<(als&7); + ac[ als>>3&7 ]++; + ac[ als&7 ]++; } bcf_fit_alt(b,max_als); + + + // Prepare BCF for output: ref, alt, filter, info, format + memset(&s, 0, sizeof(kstring_t)); kputc('\0', &s); + kputs(b->ref, &s); kputc('\0', &s); + kputs(b->alt, &s); kputc('\0', &s); kputc('\0', &s); + { + int an=0, nalts=0; + for (i=0; i0 && ac[i] ) nalts++; + } + ksprintf(&s, "AN=%d;", an); + if ( nalts ) + { + kputs("AC=", &s); + for (i=1; i0 ) kputc(',', &s); + } + kputc(';', &s); + } + kputs(b->info, &s); + anno16_t a; + int has_I16 = test16(b, &a) >= 0? 1 : 0; + if (has_I16 ) + { + if ( a.is_tested) ksprintf(&s, ";PV4=%.2g,%.2g,%.2g,%.2g", a.p[0], a.p[1], a.p[2], a.p[3]); + ksprintf(&s, ";DP4=%d,%d,%d,%d;MQ=%d", a.d[0], a.d[1], a.d[2], a.d[3], a.mq); + } + kputc('\0', &s); + rm_info(&s, "I16="); + rm_info(&s, "QS="); + } + kputs(b->fmt, &s); kputc('\0', &s); + free(b->str); + b->m_str = s.m; b->l_str = s.l; b->str = s.s; + b->qual = gts>1 ? -4.343*(ref_lk - lk_sum) : -4.343*(max_lk - lk_sum); + if ( b->qual>999 ) b->qual = 999; bcf_sync(b); + free(pdg); return gts; }