ret_t cherokee_collector_vsrv_count (cherokee_collector_vsrv_t *collector_vsrv, off_t rx, off_t tx) { /* Add it to the virtual server collector */ LOCK(collector_vsrv); base_count (COLLECTOR_BASE(collector_vsrv), rx, tx); /* Partial counting (vsrv to srv) */ collector_vsrv->srv_rx_partial += rx; collector_vsrv->srv_tx_partial += tx; if (cherokee_bogonow_now >= collector_vsrv->srv_next_update) { LOCK(collector_vsrv->srv_collector); base_count (COLLECTOR_BASE(collector_vsrv->srv_collector), collector_vsrv->srv_rx_partial, collector_vsrv->srv_tx_partial); collector_vsrv->srv_rx_partial = 0; collector_vsrv->srv_tx_partial = 0; collector_vsrv->srv_next_update = cherokee_bogonow_now + 10; UNLOCK(collector_vsrv->srv_collector); } UNLOCK(collector_vsrv); return ret_ok; }
/* used as pileup callback function which is not ideal since this can * only work on one position (has to be ensured by caller). * * No cov means I won't be called through mpileup and no output will * be generated. Non-sig pv means I'm not sure and no ouput will be * generated. Only if pv is sig we will print the var * * needs to return void to be used as function pointer to mpileup */ void uniq_snv(const plp_col_t *p, void *confp) { uniq_conf_t *conf = (uniq_conf_t *)confp; char *af_char = NULL; float af; int is_uniq = 0; int is_indel; int coverage; is_indel = vcf_var_is_indel(conf->var); #ifdef DISABLE_INDELS if (is_indel) { LOG_WARN("uniq logic can't be applied to indels." " Skipping indel var at %s %d\n", conf->var->chrom, conf->var->pos+1); return; } #endif if (0 != strcmp(p->target, conf->var->chrom) || p->pos != conf->var->pos) { LOG_ERROR("wrong pileup for var. pileup for %s %d. var for %s %d\n", p->target, p->pos+1, conf->var->chrom, conf->var->pos+1); return; } coverage = p->coverage_plp; if (is_indel) { coverage -= p->num_tails; } if (1 > coverage) { return; } if (conf->uni_freq <= 0.0) { if (! vcf_var_has_info_key(&af_char, conf->var, "AF")) { LOG_FATAL("%s\n", "Couldn't parse AF (key not found) from variant"); /* hard to catch error later */ exit(1); } af = strtof(af_char, (char **)NULL); /* atof */ free(af_char); if (af < 0.0 || af > 1.0) { float new_af; new_af = af<0.0 ? 0.01 : 1.0; /* hard to catch error later */ LOG_FATAL("Invalid (value out of bound) AF %f in variant. Resetting to %f\n", af, new_af); af = new_af; } } else { assert(conf->uni_freq <= 1.0); af = conf->uni_freq; } if (conf->use_det_lim) { /* given the current base counts and their error probs, * would we've been able to detect at given frequency. */ long double pvalues[NUM_NONCONS_BASES]; double *err_probs; /* error probs (qualities) passed down to snpcaller */ int num_err_probs; int alt_bases[NUM_NONCONS_BASES];/* actual alt bases */ int alt_counts[NUM_NONCONS_BASES]; /* counts for alt bases handed down to snpcaller */ int alt_raw_counts[NUM_NONCONS_BASES]; /* raw, unfiltered alt-counts */ varcall_conf_t varcall_conf; int bonf = 1; float alpha = 0.01; init_varcall_conf(&varcall_conf); if (debug) { dump_varcall_conf(&varcall_conf, stderr); } plp_to_errprobs(&err_probs, &num_err_probs, alt_bases, alt_counts, alt_raw_counts, p, &varcall_conf); LOG_DEBUG("at %s:%d with cov %d and num_err_probs %d\n", p->target, p->pos, coverage, num_err_probs); /* Now pretend we see AF(SNV-to-test)*coverage variant * bases. Truncate to int, i.e err on the side of caution * during rounding (assume fewer alt bases) */ alt_counts[0] = af * num_err_probs; /* don't use coverage as that is before filtering */ alt_counts[1] = alt_counts[2] = 0; if (snpcaller(pvalues, err_probs, num_err_probs, alt_counts, bonf, alpha)) { fprintf(stderr, "FATAL: snpcaller() failed at %s:%s():%d\n", __FILE__, __FUNCTION__, __LINE__); free(err_probs); return; } /* only need to test first pv */ if (pvalues[0] * (float)bonf < alpha) { /* significant value means given the counts and * qualities we would have been able to detect this * uncalled SNV had it been present at the given * frequency. But since we didn't this is a uniq * variant. * * No point in adding this as phred qual because it * means the opposite of UQ */ vcf_var_add_to_info(conf->var, uniq_flag); } LOG_VERBOSE("%s %d num_quals=%d assumed-var-counts=%d would-have-been-detectable=%d\n", conf->var->chrom, conf->var->pos+1, num_err_probs, alt_counts[0], is_uniq); free(err_probs); } else { int alt_count; double pvalue; char info_str[128]; if (is_indel) { int ref_len = strlen(conf->var->ref); int alt_len = strlen(conf->var->alt); if (ref_len > alt_len) { /* deletion */ char *del_key = malloc((strlen(conf->var->ref)+1)*sizeof(char)); strcpy(del_key, conf->var->ref+1); del_event *it_del = find_del_sequence(&p->del_event_counts, del_key); if (it_del) { alt_count = it_del->count; } else { alt_count = 0; } /* LOG_DEBUG("%s>%s k:%s c:%d\n", conf->var->ref, conf->var->alt, del_key, alt_count); */ free(del_key); } else { /* insertion */ char *ins_key = malloc((strlen(conf->var->alt)+1)*sizeof(char)); strcpy(ins_key, conf->var->alt+1); ins_event *it_ins = find_ins_sequence(&p->ins_event_counts, ins_key); if (it_ins) { alt_count = it_ins->count; } else { alt_count = 0; } /* LOG_DEBUG("%s>%s k:%s c:%d\n", conf->var->ref, conf->var->alt, ins_key, alt_count);*/ free(ins_key); } } else { alt_count = base_count(p, conf->var->alt[0]); } #ifdef DEBUG LOG_DEBUG("Now testing af=%f cov=%d alt_count=%d at %s %d for var:", af, coverage, alt_count, p->target, p->pos+1); #endif /* this is a one sided test */ if (0 != binom(&pvalue, NULL, coverage, alt_count, af)) { LOG_ERROR("%s\n", "binom() failed"); return; } snprintf(info_str, 128, "%s=%d", uniq_phred_tag, PROB_TO_PHREDQUAL_SAFE(pvalue)); vcf_var_add_to_info(conf->var, info_str); LOG_DEBUG("%s %d %s>%s AF=%f | %s (p-value=%g) | BAM alt_count=%d cov=%d (freq=%f)\n", conf->var->chrom, conf->var->pos+1, conf->var->ref, conf->var->alt, af, is_uniq ? "unique" : "not necessarily unique", pvalue, alt_count, coverage, alt_count/(float)coverage); } }