void bcf_remove_alleles(const bcf_hdr_t *header, bcf1_t *line, int rm_mask) { int i; kbitset_t *rm_set = kbs_init(line->n_allele); for (i=1; i<line->n_allele; i++) if ( rm_mask & 1<<i ) kbs_insert(rm_set, i); bcf_remove_allele_set(header, line, rm_set); kbs_destroy(rm_set); }
// Resize a bit set. static inline kbitset_t *kbs_resize(kbitset_t *bs, size_t ni) { if ( !bs ) return kbs_init(ni); size_t n = (ni + KBS_ELTBITS-1) / KBS_ELTBITS; if ( n==bs->n ) return bs; bs = (kbitset_t *) realloc(bs, sizeof(kbitset_t) + n * sizeof(unsigned long)); if ( bs==NULL ) return NULL; if ( n > bs->n ) memset(bs->b + bs->n, 0, (n - bs->n) * sizeof (unsigned long)); bs->n = n; bs->b[n] = ~0UL; return bs; }
int bcf_trim_alleles(const bcf_hdr_t *header, bcf1_t *line) { int i; bcf_fmt_t *gt = bcf_get_fmt(header, line, "GT"); if ( !gt ) return 0; int *ac = (int*) calloc(line->n_allele,sizeof(int)); // check if all alleles are populated #define BRANCH(type_t,vector_end) { \ for (i=0; i<line->n_sample; i++) \ { \ type_t *p = (type_t*) (gt->p + i*gt->size); \ int ial; \ for (ial=0; ial<gt->n; ial++) \ { \ if ( p[ial]==vector_end ) break; /* smaller ploidy */ \ if ( bcf_gt_is_missing(p[ial]) ) continue; /* missing allele */ \ if ( (p[ial]>>1)-1 >= line->n_allele ) { free(ac); return -1; } \ ac[(p[ial]>>1)-1]++; \ } \ } \ } switch (gt->type) { case BCF_BT_INT8: BRANCH(int8_t, bcf_int8_vector_end); break; case BCF_BT_INT16: BRANCH(int16_t, bcf_int16_vector_end); break; case BCF_BT_INT32: BRANCH(int32_t, bcf_int32_vector_end); break; default: fprintf(stderr, "[E::%s] todo: %d at %s:%d\n", __func__, gt->type, header->id[BCF_DT_CTG][line->rid].key, line->pos+1); exit(1); break; } #undef BRANCH int nrm = 0; kbitset_t *rm_set = kbs_init(line->n_allele); for (i=1; i<line->n_allele; i++) { if ( !ac[i] ) { kbs_insert(rm_set, i); nrm++; } } free(ac); if ( nrm ) bcf_remove_allele_set(header, line, rm_set); kbs_destroy(rm_set); return nrm; }