diff --git a/Makefile b/Makefile index 3d63a28..4e9eb3b 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ CPPFLAGS= INCLUDES= OBJS= CommandLines.o Process_Read.o Assembly.o Hash_Table.o \ POA.o Correct.o Levenshtein_distance.o Overlaps.o Trio.o kthread.o Purge_Dups.o \ - htab.o hist.o sketch.o anchor.o extract.o sys.o ksw2_extz2_sse.o hic.o rcut.o + htab.o hist.o sketch.o anchor.o extract.o sys.o ksw2_extz2_sse.o hic.o rcut.o horder.o EXE= hifiasm LIBS= -lz -lpthread -lm @@ -73,3 +73,4 @@ sketch.o: kvec.h htab.h Process_Read.h Overlaps.h kdq.h CommandLines.h sys.o: htab.h Process_Read.h Overlaps.h kvec.h kdq.h CommandLines.h hic.o: hic.h rcut.o: rcut.h +horder.o: horder.h diff --git a/Overlaps.cpp b/Overlaps.cpp index 552462b..e72746d 100644 --- a/Overlaps.cpp +++ b/Overlaps.cpp @@ -12720,6 +12720,21 @@ R_to_U* ruIndex, float chimeric_rate, float drop_ratio, int max_hang, int min_ov long long gap_fuzz, bub_label_t* b_mask_t) { hic_clean(sg); + ug_opt_t opt; memset(&opt, 0, sizeof(opt)); + opt.coverage_cut = coverage_cut; + opt.sources = sources; + opt.reverse_sources = reverse_sources; + opt.tipsLen = (asm_opt.max_short_tip*2); + opt.tip_drop_ratio = 0.15; + opt.stops_threshold = 3; + opt.ruIndex = ruIndex; + opt.chimeric_rate = 0.05; + opt.drop_ratio = 0.9; + opt.max_hang = max_hang; + opt.min_ovlp = min_ovlp; + opt.is_bench = 0; + opt.b_mask_t = b_mask_t; + kvec_asg_arc_t_warp new_rtg_edges, d_edges; kv_init(new_rtg_edges.a); kv_init(d_edges.a); @@ -12773,7 +12788,7 @@ long long gap_fuzz, bub_label_t* b_mask_t) fclose(output_file); free(gfa_name); - hic_analysis(ug, sg, cov?cov->t_ch:t_ch); + hic_analysis(ug, sg, cov?cov->t_ch:t_ch, &opt); if(cov) destory_hap_cov_t(&cov); if(t_ch) destory_trans_chain(&t_ch); @@ -13907,6 +13922,7 @@ void renew_utg(ma_ug_t **ug, asg_t* read_g, kvec_asg_arc_t_warp* edge) u = &(high_level_ug->u.a[i]); if(u->m == 0) continue; merge_unitig_content(u, (*ug), read_g, edge); + high_level_ug->g->seq[i].len = u->len; } ma_ug_destroy((*ug)); (*ug) = high_level_ug; @@ -16115,6 +16131,8 @@ kvec_asg_arc_t_warp* new_rtg_edges, bub_label_t* b_mask_t) set_drop_trio_flag(*ug); destory_hap_cov_t(&cov); + + renew_utg(ug, read_g, new_rtg_edges); } diff --git a/Overlaps.h b/Overlaps.h index 51b4d75..deb8482 100644 --- a/Overlaps.h +++ b/Overlaps.h @@ -1195,6 +1195,28 @@ uint32_t get_u_trans_spec(kv_u_trans_t *ta, uint32_t qn, uint32_t tn, u_trans_t int ma_ug_seq(ma_ug_t *g, asg_t *read_g, ma_sub_t *coverage_cut, ma_hit_t_alloc* sources, kvec_asg_arc_t_warp* edge, int max_hang, int min_ovlp, kvec_asg_arc_t_warp *E, uint32_t is_polish); + +typedef struct{ + ma_sub_t* coverage_cut; + ma_hit_t_alloc* sources; + ma_hit_t_alloc* reverse_sources; + long long tipsLen; + float tip_drop_ratio; + long long stops_threshold; + R_to_U* ruIndex; + float chimeric_rate; + float drop_ratio; + int max_hang; + int min_ovlp; + int is_bench; + bub_label_t* b_mask_t; +}ug_opt_t; + +void adjust_utg_by_trio(ma_ug_t **ug, asg_t* read_g, uint8_t flag, float drop_rate, +ma_hit_t_alloc* sources, ma_hit_t_alloc* reverse_sources, ma_sub_t* coverage_cut, +long long tipsLen, float tip_drop_ratio, long long stops_threshold, +R_to_U* ruIndex, float chimeric_rate, float drop_ratio, int max_hang, int min_ovlp, +kvec_asg_arc_t_warp* new_rtg_edges, bub_label_t* b_mask_t); #define JUNK_COV 5 #define DISCARD_RATE 0.8 diff --git a/hic.cpp b/hic.cpp index ac582e2..776e718 100644 --- a/hic.cpp +++ b/hic.cpp @@ -14,6 +14,7 @@ #include "ksort.h" #include "kseq.h" // FASTA/Q parser #include "kdq.h" +#include "horder.h" KSEQ_INIT(gzFile, gzread) KDQ_INIT(uint64_t) @@ -190,22 +191,10 @@ typedef struct { uint64_t n_u; } kvec_pe_hit_hap; - -typedef struct { - uint64_t s, e, id, len; -} pe_hit; - -typedef struct { - kvec_t(pe_hit) a; - kvec_t(uint64_t) idx; - kvec_t(uint64_t) occ; -} kvec_pe_hit; - typedef struct { kvec_t(hc_edge) a; }kvec_hc_edge; - #define pe_hit_an1_key(x) ((x).s) KRADIX_SORT_INIT(pe_hit_an1, pe_hit, pe_hit_an1_key, member_size(pe_hit, s)) #define pe_hit_an2_key(x) ((x).e) @@ -286,6 +275,11 @@ KRADIX_SORT_INIT(hc_s_hit_off_cnt, s_hit, hc_s_hit_off_cnt_key, 8) KRADIX_SORT_INIT(hc_edge_u, hc_edge, hc_edge_key_u, 4) #define hc_edge_key_d(a) ((a).dis) KRADIX_SORT_INIT(hc_edge_d, hc_edge, hc_edge_key_d, member_size(hc_edge, dis)) +#define get_hit_suid(x, k) (((x).a.a[(k)].s<<1)>>(64 - (x).uID_bits)) +#define get_hit_spos(x, k) ((x).a.a[(k)].s & (x).pos_mode) +#define get_hit_euid(x, k) (((x).a.a[(k)].e<<1)>>(64 - (x).uID_bits)) +#define get_hit_epos(x, k) ((x).a.a[(k)].e & (x).pos_mode) + typedef struct { kvec_t(kvec_t_u64_warp) matrix; @@ -302,7 +296,6 @@ typedef struct{ uint64_t max, med; } trans_idx; - reads_t R1, R2; ha_ug_index* ug_index; @@ -15431,7 +15424,7 @@ void print_kv_u_trans_t(kv_u_trans_t *ta) fprintf(stderr, "[M::%s::] \n", __func__); } -int hic_short_align(const enzyme *fn1, const enzyme *fn2, ha_ug_index* idx) +int hic_short_align(const enzyme *fn1, const enzyme *fn2, ha_ug_index* idx, ug_opt_t *opt) { double index_time = yak_realtime(); sldat_t sl; @@ -15503,6 +15496,8 @@ int hic_short_align(const enzyme *fn1, const enzyme *fn2, ha_ug_index* idx) verbose_het_stat(&bub); + horder_t *ho = init_horder_t(&sl.hits, idx->uID_bits, idx->pos_mode, idx->read_g, idx->ug, &bub, opt); + ///print_hc_links(&link, 0, &hap); // print_kv_u_trans(&k_trans, &link, s->s); @@ -15514,6 +15509,7 @@ int hic_short_align(const enzyme *fn1, const enzyme *fn2, ha_ug_index* idx) ///print_debug_bubble_graph(&bub, idx->ug, asm_opt.output_file_name); // print_bubble_chain(&bub); // destory_contig_partition(&hap); + destory_horder_t(&ho); kv_destroy(back_hc_edge.a); kv_destroy(sl.hits.a); kv_destroy(sl.hits.idx); @@ -15542,7 +15538,7 @@ int hic_short_align(const enzyme *fn1, const enzyme *fn2, ha_ug_index* idx) } -void hic_analysis(ma_ug_t *ug, asg_t* read_g, trans_chain* t_ch) +void hic_analysis(ma_ug_t *ug, asg_t* read_g, trans_chain* t_ch, ug_opt_t *opt) { ug_index = NULL; int exist = (asm_opt.load_index_from_disk? @@ -15553,7 +15549,7 @@ void hic_analysis(ma_ug_t *ug, asg_t* read_g, trans_chain* t_ch) ug_index->read_g = read_g; ug_index->t_ch = t_ch; ///test_unitig_index(ug_index, ug); - hic_short_align(asm_opt.hic_reads[0], asm_opt.hic_reads[1], ug_index); + hic_short_align(asm_opt.hic_reads[0], asm_opt.hic_reads[1], ug_index, opt); destory_hc_pt_index(ug_index); } diff --git a/hic.h b/hic.h index dd3e71b..6a197b0 100644 --- a/hic.h +++ b/hic.h @@ -11,7 +11,7 @@ hc_edge* get_hc_edge(hc_links* link, uint64_t src, uint64_t dest, uint64_t dir); hc_edge* push_hc_edge(hc_linkeage* x, uint64_t uID, double weight, int dir, uint64_t* d); -void hic_analysis(ma_ug_t *ug, asg_t* read_g, trans_chain* t_ch); +void hic_analysis(ma_ug_t *ug, asg_t* read_g, trans_chain* t_ch, ug_opt_t *opt); void hic_benchmark(ma_ug_t *ug, asg_t* read_g); typedef struct { @@ -54,6 +54,19 @@ typedef struct { int8_t *s; uint64_t xs; } ps_t; + +typedef struct { + uint64_t s, e, id, len; +} pe_hit; + +typedef struct { + kvec_t(pe_hit) a; + kvec_t(uint64_t) idx; + kvec_t(uint64_t) occ; + uint64_t uID_bits; + uint64_t pos_mode; +} kvec_pe_hit; + #define P_het(B) ((B).num.n) #define M_het(B) ((B).num.n + 1) // #define IF_BUB(ID, B) ((B).index[(ID)] < (B).num.n) diff --git a/horder.cpp b/horder.cpp new file mode 100644 index 0000000..b1939da --- /dev/null +++ b/horder.cpp @@ -0,0 +1,348 @@ +#define __STDC_LIMIT_MACROS +#include "float.h" +#include "horder.h" +#include +#include "hic.h" +#include "htab.h" +#include "assert.h" +#include "Overlaps.h" +#include "Hash_Table.h" +#include "Correct.h" +#include "Purge_Dups.h" +#include "rcut.h" +#include "khashl.h" +#include "kthread.h" +#include "ksort.h" +#include "kseq.h" // FASTA/Q parser +#include "kdq.h" +KSEQ_INIT(gzFile, gzread) +KDQ_INIT(uint64_t) +#define pe_hit_an1_idx_key(x) ((x).s<<1) +KRADIX_SORT_INIT(pe_hit_idx_hn1, pe_hit, pe_hit_an1_idx_key, member_size(pe_hit, s)) +#define pe_hit_an2_idx_key(x) ((x).e<<1) +KRADIX_SORT_INIT(pe_hit_idx_hn2, pe_hit, pe_hit_an2_idx_key, member_size(pe_hit, e)) +#define get_hit_suid(x, k) (((x).a.a[(k)].s<<1)>>(64 - (x).uID_bits)) +#define get_hit_spos(x, k) ((x).a.a[(k)].s & (x).pos_mode) +#define get_hit_euid(x, k) (((x).a.a[(k)].e<<1)>>(64 - (x).uID_bits)) +#define get_hit_epos(x, k) ((x).a.a[(k)].e & (x).pos_mode) + +typedef struct { + uint64_t ruid; + uint64_t off; +} hit_aux_t; + +typedef struct { + hit_aux_t *a; + size_t n, m; + kvec_t(uint64_t) idx; +} u_hits_t; + + +#define hit_aux_ruid_key(x) ((x).ruid) +KRADIX_SORT_INIT(hit_aux_ruid, hit_aux_t, hit_aux_ruid_key, member_size(hit_aux_t, ruid)) + + +void get_r_hits(kvec_pe_hit *u_hits, kvec_pe_hit *r_hits, asg_t* r_g, ma_ug_t* ug, bubble_type* bub, uint64_t uID_bits, uint64_t pos_mode) +{ + uint64_t k, l, i, r_i, offset, rid, rev, rBeg, rEnd, ubits, p_mode, upos, rpos, update; + ma_utg_t *u = NULL; + memset(r_hits, 0, sizeof(*r_hits)); + r_hits->uID_bits = uID_bits; + r_hits->pos_mode = pos_mode; + //reset for reads + for (ubits=1; (uint64_t)(1<n_seq; ubits++); + p_mode = ((uint64_t)-1) >> (ubits + 1); + + kv_malloc(r_hits->a, u_hits->a.n); r_hits->a.n = r_hits->a.m = u_hits->a.n; + memcpy(r_hits->a.a, u_hits->a.a, r_hits->a.n*sizeof(pe_hit)); + radix_sort_pe_hit_idx_hn1(r_hits->a.a, r_hits->a.a + r_hits->a.n); + for (k = 1, l = 0; k <= r_hits->a.n; ++k) + { + if (k == r_hits->a.n || get_hit_suid(*r_hits, k) != get_hit_suid(*r_hits, l))//same suid + { + ///already sort by spos + u = &(ug->u.a[get_hit_suid(*r_hits, l)]); + update = 0; + for (i = offset = 0, r_i = l; i < u->n; i++) + { + rid = u->a[i]>>33; + rBeg = offset; + rEnd = rBeg + r_g->seq[rid].len - 1; + for (; r_i < k; r_i++) + { + upos = get_hit_spos(*r_hits, r_i);///pos at unitig + if(upos > rEnd) break; + if(upos >= rBeg && upos <= rEnd) + { + if(bub) + { + r_hits->a.a[r_i].id = (uint32_t)r_hits->a.a[r_i].id; + if(!IF_HOM(get_hit_suid(*r_hits, r_i), *bub)) + { + r_hits->a.a[r_i].id += ((uint64_t)(1)<<32); + } + } + + rpos = (((u->a[i]>>32)&1)? rEnd - upos : upos - rBeg);///pos at read + rev = ((u->a[i]>>32)&1) ^ (r_hits->a.a[r_i].s>>63); + r_hits->a.a[r_i].s = (rev<<63) | ((rid << (64-ubits))>>1) | (rpos & p_mode); + + update++; + } + } + offset += (uint32_t)u->a[i]; + } + + if(r_i != k || update != k - l) fprintf(stderr, "ERROR-r_i\n"); + l = k; + } + } + + radix_sort_pe_hit_idx_hn2(r_hits->a.a, r_hits->a.a + r_hits->a.n); + for (k = 1, l = 0; k <= r_hits->a.n; ++k) + { + if (k == r_hits->a.n || get_hit_euid(*r_hits, k) != get_hit_euid(*r_hits, l))//same euid + { + ///already sort by epos + u = &(ug->u.a[get_hit_euid(*r_hits, l)]); + update = 0; + for (i = offset = 0, r_i = l; i < u->n; i++) + { + rid = u->a[i]>>33; + rBeg = offset; + rEnd = rBeg + r_g->seq[rid].len - 1; + for (; r_i < k; r_i++) + { + upos = get_hit_epos(*r_hits, r_i);///pos at unitig + if(upos > rEnd) break; + if(upos >= rBeg && upos <= rEnd) + { + if(bub) + { + r_hits->a.a[r_i].id >>= 32; + r_hits->a.a[r_i].id <<= 32; + if(!IF_HOM(get_hit_euid(*r_hits, r_i), *bub)) + { + r_hits->a.a[r_i].id += 1; + } + } + + rpos = (((u->a[i]>>32)&1)? rEnd - upos : upos - rBeg);///pos at read + rev = ((u->a[i]>>32)&1) ^ (r_hits->a.a[r_i].e>>63); + r_hits->a.a[r_i].e = (rev<<63) | ((rid << (64-ubits))>>1) | (rpos & p_mode); + + update++; + } + } + offset += (uint32_t)u->a[i]; + } + + if(r_i != k || update != k - l) fprintf(stderr, "ERROR-r_i\n"); + l = k; + } + } + + r_hits->uID_bits = ubits; + r_hits->pos_mode = p_mode; +} + +uint64_t get_corresp_usite(uint64_t rid, uint64_t rpos, uint64_t rev, uint64_t rlen, u_hits_t *x, uint64_t ubits, uint64_t p_mode, kvec_t_u64_warp *buf) +{ + hit_aux_t *a = NULL; + uint64_t a_n, i, new_uid, new_pos, new_rev; + + a = x->a + (x->idx.a[rid]>>32); + a_n = (uint32_t)x->idx.a[rid]; + for (i = 0; i < a_n; i++) + { + new_uid = (uint32_t)a[i].ruid; + new_pos = (((a[i].ruid>>32)&1)? a[i].off + rlen - 1 - rpos : a[i].off + rpos); + new_rev = ((a[i].ruid>>32)&1)^rev; + kv_push(uint64_t, buf->a, (new_rev<<63) | ((new_uid << (64-ubits))>>1) | (new_pos & p_mode)); + } + + return a_n; +} + +void update_u_hits(kvec_pe_hit *u_hits, kvec_pe_hit *r_hits, ma_ug_t* ug, asg_t* r_g) +{ + u_hits_t x; memset(&x, 0, sizeof(x)); + hit_aux_t *p = NULL; + ma_utg_t *u = NULL; + pe_hit *t = NULL; + uint64_t v, i, l, k, offset, occ_1, occ_2, *a_1, *a_2, i_1, i_2; + + for (v = 0; v < ug->g->n_seq; v++) + { + u = &(ug->u.a[v]); + for (i = offset = 0; i < u->n; i++) + { + kv_pushp(hit_aux_t, x, &p); + p->ruid = u->a[i]>>32; + p->ruid <<= 32; + p->ruid |= v; + p->off = offset; + offset += (uint32_t)u->a[i]; + } + } + + radix_sort_hit_aux_ruid(x.a, x.a + x.n); + x.idx.n = x.idx.m = (x.n?(x.a[x.n-1].ruid>>33)+1:0); + CALLOC(x.idx.a, x.idx.n); + for (k = 1, l = 0; k <= x.n; ++k) + { + if (k == x.n || (x.a[k].ruid>>33) != (x.a[l].ruid>>33))//same rid + { + x.idx.a[x.a[l].ruid>>33] = (uint64_t)l << 32 | (k - l); + l = k; + } + } + + u_hits->a.n = u_hits->idx.n = u_hits->occ.n = 0; + for (u_hits->uID_bits=1; (uint64_t)(1<uID_bits)<(uint64_t)ug->g->n_seq; u_hits->uID_bits++); + u_hits->pos_mode = ((uint64_t)-1) >> (u_hits->uID_bits + 1); + kvec_t_u64_warp buf; kv_init(buf.a); + + for (i = 0; i < r_hits->a.n; i++) + { + buf.a.n = 0; + occ_1 = get_corresp_usite(get_hit_suid(*r_hits, i), get_hit_spos(*r_hits, i), + r_hits->a.a[i].s>>63, r_g->seq[get_hit_suid(*r_hits, i)].len, &x, u_hits->uID_bits, + u_hits->pos_mode, &buf); + occ_2 = get_corresp_usite(get_hit_euid(*r_hits, i), get_hit_epos(*r_hits, i), + r_hits->a.a[i].e>>63, r_g->seq[get_hit_euid(*r_hits, i)].len, &x, u_hits->uID_bits, + u_hits->pos_mode, &buf); + if(occ_1 == 0 || occ_2 == 0) continue; + a_1 = buf.a.a; a_2 = buf.a.a + occ_1; + for (i_1 = 0; i_1 < occ_1; i_1++) + { + for (i_2 = 0; i_2 < occ_2; i_2++) + { + kv_pushp(pe_hit, u_hits->a, &t); + t->id = r_hits->a.a[i].id; + t->len = r_hits->a.a[i].len; + t->s = a_1[i_1]; + t->e = a_2[i_2]; + } + } + } + + + free(x.a); free(x.idx.a); kv_destroy(buf.a); +} + +ma_ug_t* get_trio_unitig_graph(asg_t *sg, uint8_t flag, ug_opt_t *opt) +{ + kvec_asg_arc_t_warp new_rtg_edges; + kv_init(new_rtg_edges.a); + + ma_ug_t *ug = NULL; + ug = ma_ug_gen(sg); + + adjust_utg_by_trio(&ug, sg, flag, TRIO_THRES, opt->sources, opt->reverse_sources, + opt->coverage_cut, opt->tipsLen, opt->tip_drop_ratio, opt->stops_threshold, + opt->ruIndex, opt->chimeric_rate, opt->drop_ratio, opt->max_hang, opt->min_ovlp, + &new_rtg_edges, opt->b_mask_t); + + kv_destroy(new_rtg_edges.a); + return ug; +} + +void generate_haplotypes(horder_t *h, ug_opt_t *opt) +{ + uint64_t i, off; + ma_ug_t *ug_1 = NULL, *ug_2 = NULL; + asg_cleanup(h->r_g); + asg_arc_del_trans(h->r_g, asm_opt.gap_fuzz);///must + + ug_1 = get_trio_unitig_graph(h->r_g, FATHER, opt); + ug_2 = get_trio_unitig_graph(h->r_g, MOTHER, opt); + h->ug = ug_1; + + off = ug_1->g->n_seq; + ///update graph + for (i = 0; i < ug_2->g->n_seq; i++) + { + asg_seq_set(h->ug->g, off + i, ug_2->g->seq[i].len, ug_2->g->seq[i].del); + } + + asg_arc_t *p = NULL; + for (i = 0; i < ug_2->g->n_arc; i++) + { + p = asg_arc_pushp(h->ug->g); + *p = ug_2->g->arc[i]; + p->v += (off<<1); + p->ul += (off<<33); + } + free(h->ug->g->idx); + h->ug->g->idx = 0; + h->ug->g->is_srt = 0; + asg_cleanup(h->ug->g); + + + + ///update unitigs + ma_utg_t *pu = NULL; + for (i = 0; i < ug_2->u.n; i++) + { + kv_pushp(ma_utg_t, h->ug->u, &pu); + *pu = ug_2->u.a[i]; + ug_2->u.a[i].a = NULL; + ug_2->u.a[i].s = NULL; + } + + for (i = 0; i < h->ug->g->n_seq; i++) + { + h->ug->g->seq[i].c = (i < off? FATHER:MOTHER); + } + /*******************************for debug************************************/ + if(h->ug->g->n_seq != h->ug->u.n) + { + fprintf(stderr, "ERROR-non-equal-length\n"); + } + fprintf(stderr, "h->ug->u.n-%u, off-%lu, ug_2->u.n-%u\n", (uint32_t)h->ug->u.n, off, (uint32_t)ug_2->u.n); + for (i = 0; i < h->ug->g->n_seq; i++) + { + if(h->ug->g->seq[i].len != h->ug->u.a[i].len) + { + fprintf(stderr, "****ERROR-1-%lu: g->seq[i].len-%u, u.a[i].len-%u\n", + i, (uint32_t)h->ug->g->seq[i].len, (uint32_t)h->ug->u.a[i].len); + } + pu = i < off? (&ug_1->u.a[i]) : (&ug_2->u.a[i - off]); + if(h->ug->g->seq[i].len != pu->len) + { + fprintf(stderr, "ERROR-2\n"); + } + } + + /*******************************for debug************************************/ + ug_1 = NULL; + ma_ug_destroy(ug_2); +} + +horder_t *init_horder_t(kvec_pe_hit *i_hits, uint64_t i_hits_uid_bits, uint64_t i_hits_pos_mode, +asg_t *i_rg, ma_ug_t* i_ug, bubble_type* bub, ug_opt_t *opt) +{ + horder_t *h = NULL; CALLOC(h, 1); + get_r_hits(i_hits, &(h->r_hits), i_rg, i_ug, bub, i_hits_uid_bits, i_hits_pos_mode); + h->r_g = copy_read_graph(i_rg); + generate_haplotypes(h, opt); + update_u_hits(&(h->u_hits), &(h->r_hits), h->ug, h->r_g); + + return h; +} + +void destory_horder_t(horder_t **h) +{ + kv_destroy((*h)->r_hits.a); + kv_destroy((*h)->r_hits.idx); + kv_destroy((*h)->r_hits.occ); + + kv_destroy((*h)->u_hits.a); + kv_destroy((*h)->u_hits.idx); + kv_destroy((*h)->u_hits.occ); + + ma_ug_destroy((*h)->ug); + asg_destroy((*h)->r_g); + free((*h)); +} \ No newline at end of file diff --git a/horder.h b/horder.h new file mode 100644 index 0000000..f71738b --- /dev/null +++ b/horder.h @@ -0,0 +1,14 @@ +#ifndef __HORDER__ +#define __HORDER__ +#include +#include "hic.h" +typedef struct { + kvec_pe_hit r_hits, u_hits; + ma_ug_t* ug; + asg_t* r_g; +}horder_t; + +horder_t *init_horder_t(kvec_pe_hit *i_hits, uint64_t i_hits_uid_bits, uint64_t i_hits_pos_mode, +asg_t *i_rg, ma_ug_t* i_ug, bubble_type* bub, ug_opt_t *opt); +void destory_horder_t(horder_t **h); +#endif