-
-void calc_vdb(int n, const bcf_callret1_t *calls, bcf_call_t *call)
-{
- // Variant distance bias. Samples merged by means of DP-weighted average.
-
- float weight=0, tot_prob=0;
-
- int i;
- for (i=0; i<n; i++)
- {
- int mvd = calls[i].mvd[0];
- int dp = calls[i].mvd[1];
- int read_len = calls[i].mvd[2];
-
- if ( dp<2 ) continue;
-
- float prob = 0;
- if ( dp==2 )
- {
- // Exact formula
- prob = (mvd==0) ? 1.0/read_len : (read_len-mvd)*2.0/read_len/read_len;
- }
- else if ( dp==3 )
- {
- // Sin, quite accurate approximation
- float mu = read_len/2.9;
- prob = mvd>2*mu ? 0 : sin(mvd*3.14/2/mu) / (4*mu/3.14);
- }
- else
- {
- // Scaled gaussian curve, crude approximation, but behaves well. Using fixed depth for bigger depths.
- if ( dp>5 )
- dp = 5;
- float sigma2 = (read_len/1.9/(dp+1)) * (read_len/1.9/(dp+1));
- float norm = 1.125*sqrt(2*3.14*sigma2);
- float mu = read_len/2.9;
- if ( mvd < mu )
- prob = exp(-(mvd-mu)*(mvd-mu)/2/sigma2)/norm;
- else
- prob = exp(-(mvd-mu)*(mvd-mu)/3.125/sigma2)/norm;
- }
-
- //fprintf(pysamerr,"dp=%d mvd=%d read_len=%d -> prob=%f\n", dp,mvd,read_len,prob);
- tot_prob += prob*dp;
- weight += dp;
- }
- tot_prob = weight ? tot_prob/weight : 1;
- //fprintf(pysamerr,"prob=%f\n", tot_prob);
- call->vdb = tot_prob;
-}
-