#include <errno.h>
#include <assert.h>
#include <limits.h>
+#include <zlib.h>
#include "prob1.h"
#include "kstring.h"
#define MC_EM_EPS 1e-5
#define MC_DEF_INDEL 0.15
+gzFile bcf_p1_fp_lk;
+
unsigned char seq_nt4_table[256] = {
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
return ma;
}
+int bcf_p1_get_M(bcf_p1aux_t *b) { return b->M; }
+
int bcf_p1_set_n1(bcf_p1aux_t *b, int n1)
{
if (n1 == 0 || n1 >= b->n) return -1;
}
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)
{
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;
}
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; i<ma->n; i++)
{
int j;
- float sum = 0;
+ double sum = 0;
for (j=0; j<npdg; j++)
{
- _pdg[j] = pow(10,-0.1*pl[j]);
+ //_pdg[j] = pow(10,-0.1*pl[j]);
+ _pdg[j] = ma->q2p[pl[j]];
sum += _pdg[j];
}
if ( sum )
}
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; ia<nals; ia++)
{
- //if ( ia && qsum[ia]==0 ) continue;
- float lk_tot = 0;
+ double lk_tot = 0;
int iaa = (ia+1)*(ia+2)/2-1;
int isample;
for (isample=0; isample<ma->n; 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_lk<lk_tot ) { max_lk2 = max_lk; max_als2 = max_als; max_lk = lk_tot; max_als = 1<<ia; }
else if ( max_lk2<lk_tot ) { max_lk2 = lk_tot; max_als2 = 1<<ia; }
lk_sum = lk_tot>lk_sum ? lk_tot + log(1+exp(lk_sum-lk_tot)) : lk_sum + log(1+exp(lk_tot-lk_sum));
}
- for (ia=0; ia<nals; ia++)
+ if ( nals>1 )
{
- if ( qsum[ia]==0 ) continue;
- //if ( ia && qsum[ia]==0 ) continue;
- for (ib=0; ib<ia; ib++)
+ for (ia=0; ia<nals; ia++)
{
- if ( qsum[ib]==0 ) continue;
- //if ( ib && qsum[ib]==0 ) continue;
- //if ( qsum[ia]+qsum[ib]==0 ) continue;
- float lk_tot = 0;
- float fa = qsum[ia]/(qsum[ia]+qsum[ib]);
- float fb = qsum[ib]/(qsum[ia]+qsum[ib]);
- float fab = 2*fa*fb; fa *= fa; fb *= fb;
- int isample, iaa = (ia+1)*(ia+2)/2-1, ibb = (ib+1)*(ib+2)/2-1, iab = iaa - ia + ib;
- for (isample=0; isample<ma->n; isample++)
+ if ( qsum[ia]==0 ) continue;
+ int iaa = (ia+1)*(ia+2)/2-1;
+ for (ib=0; ib<ia; ib++)
{
- if ( b->ploidy && 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; isample<ma->n; isample++)
+ {
+ double *p = pdg + isample*npdg;
+ //assert( log(fa*p[iaa] + fb*p[ibb] + fab*p[iab]) <= 0 );
+ if ( b->ploidy && b->ploidy[isample]==1 )
+ lk_tot += log(fa*p[iaa] + fb*p[ibb]);
+ else
+ lk_tot += log(fa*p[iaa] + fb*p[ibb] + fab*p[iab]);
+ }
+ if ( max_lk<lk_tot ) { max_lk2 = max_lk; max_als2 = max_als; max_lk = lk_tot; max_als = 1<<ia|1<<ib; }
+ else if ( max_lk2<lk_tot ) { max_lk2 = lk_tot; max_als2 = 1<<ia|1<<ib; }
+ lk_sum = lk_tot>lk_sum ? lk_tot + log(1+exp(lk_sum-lk_tot)) : lk_sum + log(1+exp(lk_tot-lk_sum));
}
- if ( max_lk<lk_tot ) { max_lk2 = max_lk; max_als2 = max_als; max_lk = lk_tot; max_als = 1<<ia|1<<ib; }
- else if ( max_lk2<lk_tot ) { max_lk2 = lk_tot; max_als2 = 1<<ia|1<<ib; }
- lk_sum = lk_tot>lk_sum ? lk_tot + log(1+exp(lk_sum-lk_tot)) : lk_sum + log(1+exp(lk_tot-lk_sum));
}
}
- for (ia=0; ia<nals; ia++)
+ if ( nals>2 )
{
- if ( qsum[ia]==0 ) continue;
- //if ( ia && qsum[ia]==0 ) continue;
- for (ib=0; ib<ia; ib++)
+ for (ia=0; ia<nals; ia++)
{
- if ( qsum[ib]==0 ) continue;
- //if ( ib && qsum[ib]==0 ) continue;
- for (ic=0; ic<ib; ic++)
+ if ( qsum[ia]==0 ) continue;
+ int iaa = (ia+1)*(ia+2)/2-1;
+ for (ib=0; ib<ia; ib++)
{
- if ( qsum[ic]==0 ) continue;
- //if ( ic && qsum[ic]==0 ) continue;
- //if ( qsum[ia]+qsum[ib]+qsum[ic]==0 ) continue;
- float lk_tot = 0;
- float fa = qsum[ia]/(qsum[ia]+qsum[ib]+qsum[ic]);
- float fb = qsum[ib]/(qsum[ia]+qsum[ib]+qsum[ic]);
- float fc = qsum[ic]/(qsum[ia]+qsum[ib]+qsum[ic]);
- float fab = 2*fa*fb, fac = 2*fa*fc, fbc = 2*fb*fc; fa *= fa; fb *= fb; fc *= fc;
- int isample, iaa = (ia+1)*(ia+2)/2-1, ibb = (ib+1)*(ib+2)/2-1, icc = (ic+1)*(ic+2)/2-1;
- int iab = iaa - ia + ib, iac = iaa - ia + ic, ibc = ibb - ib + ic;
- for (isample=0; isample<ma->n; isample++)
+ if ( qsum[ib]==0 ) continue;
+ int ibb = (ib+1)*(ib+2)/2-1;
+ int iab = iaa - ia + ib;
+ for (ic=0; ic<ib; ic++)
{
- if ( b->ploidy && 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; isample<ma->n; isample++)
+ {
+ 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 );
+ if ( b->ploidy && b->ploidy[isample]==1 )
+ lk_tot += log(fa*p[iaa] + fb*p[ibb] + fc*p[icc]);
+ else
+ lk_tot += log(fa*p[iaa] + fb*p[ibb] + fc*p[icc] + fab*p[iab] + fac*p[iac] + fbc*p[ibc]);
+ }
+ if ( max_lk<lk_tot ) { max_lk2 = max_lk; max_als2 = max_als; max_lk = lk_tot; max_als = 1<<ia|1<<ib|1<<ic; }
+ else if ( max_lk2<lk_tot ) { max_lk2 = lk_tot; max_als2 = 1<<ia|1<<ib|1<<ic; }
+ lk_sum = lk_tot>lk_sum ? lk_tot + log(1+exp(lk_sum-lk_tot)) : lk_sum + log(1+exp(lk_tot-lk_sum));
}
- if ( max_lk<lk_tot ) { max_lk2 = max_lk; max_als2 = max_als; max_lk = lk_tot; max_als = 1<<ia|1<<ib|1<<ic; }
- else if ( max_lk2<lk_tot ) { max_lk2 = lk_tot; max_als2 = 1<<ia|1<<ib|1<<ic; }
- lk_sum = lk_tot>lk_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; i<nals; i++) if ( max_als&1<<i) n1++;
for (i=0; i<nals; i++) if ( max_als2&1<<i) n2++;
max_als = max_als2;
}
- // Get the BCF record ready for output
+ // Get the BCF record ready for GT and GQ
kstring_t s;
- 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);
- 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<nals; ia++)
{
if ( !(max_als&1<<ia) ) continue;
int iaa = (ia+1)*(ia+2)/2-1;
- float _lk = p[iaa]*qsum[ia]*qsum[ia];
+ double _lk = p[iaa]*qsum[ia]*qsum[ia];
if ( _lk > lk ) { lk = _lk; als = ia<<3 | ia; }
lk_sum += _lk;
}
{
if ( !(max_als&1<<ib) ) continue;
int iab = iaa - ia + ib;
- float _lk = 2*qsum[ia]*qsum[ib]*p[iab];
+ double _lk = 2*qsum[ia]*qsum[ib]*p[iab];
if ( _lk > lk ) { lk = _lk; als = ib<<3 | ia; }
lk_sum += _lk;
}
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; i<nals; i++)
+ {
+ an += ac[i];
+ if ( i>0 && ac[i] ) nalts++;
+ }
+ ksprintf(&s, "AN=%d;", an);
+ if ( nalts )
+ {
+ kputs("AC=", &s);
+ for (i=1; i<nals; i++)
+ {
+ if ( !(gts&1<<i) ) continue;
+ nalts--;
+ ksprintf(&s,"%d", ac[i]);
+ if ( nalts>0 ) 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;
}
}
}
if (z[0] != ma->z) memcpy(ma->z, z[0], sizeof(double) * (ma->M + 1));
+ if (bcf_p1_fp_lk)
+ gzwrite(bcf_p1_fp_lk, ma->z, sizeof(double) * (ma->M + 1));
}
static void mc_cal_y(bcf_p1aux_t *ma)