// File: /workspace/github_cpp_makefile_star2_O2/chhylp123[P]hifiasm/Correct.cpp
// Function: ul_local_aln(overlap_region*, Candidates_list*, ul_idx_t const*, char*, UC_Read*, bit_extz_t*, double, long, unsigned long, double, kv_ul_ov_t*, kv_ul_ov_t*, kv_rtrace_t*, unsigned long, unsigned long, unsigned long, unsigned long, overlap_region*)
uint64_t ul_local_aln(overlap_region *z, Candidates_list *cl, const ul_idx_t *udb, char* qstr, UC_Read *tu, 
bit_extz_t *exz, double e_rate, int64_t w_l, uint64_t min_ovlp, double o_rate, kv_ul_ov_t *rln, kv_ul_ov_t *cln,
kv_rtrace_t *trace, uint64_t ql, uint64_t rid, uint64_t oid, uint64_t khit, overlap_region *aux_o)
{   
    uint64_t ol, aln_ol, cn, k, mm, rln_0; ul_contain *ct = udb->ct; utg_ct_t *ca; ul_ov_t *p;
    if(!aux_o) {
        align_ul_ed_post_extz(z, udb, NULL, qstr, tu->seq, exz, e_rate, w_l, -1, 1, NULL); 
        ol = z->x_pos_e+1-z->x_pos_s, aln_ol = z->align_length;
        if(aln_ol >= (ol*o_rate)) return 1;
        if(aln_ol <= min_ovlp) return 0;
        // fprintf(stderr, "***[M::%s::aln_ol->%lu] utg%.6dl(%c), align::%u, q::[%u, %u), t::[%u, %u)\n", __func__, aln_ol,
        //         (int32_t)z->y_id + 1, "+-"[z->y_pos_strand], z->align_length,
        //         z->x_pos_s, z->x_pos_e+1, z->y_pos_s, z->y_pos_e+1);
        mm = win_cluster_fliter(z->w_list.a, z->w_list.n, min_ovlp, o_rate/2);
        // print_aln_windows(z);
        // fprintf(stderr, "***[M::%s::] mm::%lu\n", __func__, mm);
        return mm;
    } else {
        ol = z->x_pos_e+1-z->x_pos_s; aln_ol = z->align_length;
        if(aln_ol <= min_ovlp) return 0;
        // if(z->y_id == 700) {
        //     fprintf(stderr, "+[M::%s::aln_ol->%lu::o_rate->%f] utg%.6dl(%c), align::%u, q::[%u, %u), t::[%u, %u), ql::%lu\n", 
        //             __func__, aln_ol, o_rate, 
        //             (int32_t)z->y_id + 1, "+-"[z->y_pos_strand], z->align_length,
        //             z->x_pos_s, z->x_pos_e+1, z->y_pos_s, z->y_pos_e+1, ql);
        //     print_aln_windows(z);
        // }
        rln_0 = rln->n;
        if((ol*o_rate) <= aln_ol) {
            kv_pushp(ul_ov_t, *rln, &p); memset(p, 0, sizeof(*p));
            ///[ts, te) -> whole interval rid at the unitig adjusted by the reverse 
            p->ts = z->y_pos_s; p->te = z->y_pos_e+1; 
            p->qs = z->x_pos_s; p->qe = z->x_pos_e+1;
            p->rev = z->y_pos_strand; p->el = 0; p->tn = p->qn = (uint32_t)-1;
        } else {
            cn = ((uint32_t)(ct->idx.a[z->y_id])); 
            ca = ct->rids.a + ((ct->idx.a[z->y_id])>>32);
            gen_sub_ov_adv(udb, z, o_rate, NULL, 0, rln);
            gen_sub_ov_adv(udb, z, o_rate, ca, cn, rln);
        }

        if(rln->n <= rln_0) return 0;
        radix_sort_ul_ov_srt_qs1(rln->a+rln_0, rln->a+rln->n);
        // if(z->y_id == 700) {
        //     for (k = 0; k < rln->n; k++) {
        //         p = &(rln->a[k]);
        //         fprintf(stderr, "+[M::%s::k->%lu] candidate_q::[%u, %u)\n", __func__, k, p->qs, p->qe);
        //     }
        // }

        for (k = mm = rln_0, p = NULL; k < rln->n; k++) {
            if((!p) || (rln->a[k].qs >= p->qe)) p = NULL;
            if(p) {
                if((rln->a[k].qs<p->qe)&&(rln->a[k].qe>p->qe)) {
                    p->qe = rln->a[k].qe; 
                }
            } else {
                p = &(rln->a[mm++]); *p = rln->a[k];
            }
        }
        rln->n = mm;
        // if(z->y_id == 700) {
        //     for (k = 0; k < rln->n; k++) {
        //         p = &(rln->a[k]);
        //         fprintf(stderr, "-[M::%s::k->%lu] candidate_q::[%u, %u)\n", __func__, k, p->qs, p->qe);
        //     }
        // }

        return_t_chain(z, cl);
        cigar_gen_by_chain_adv_local(z, cl, rln->a+rln_0, rln->n-rln_0, w_l, udb, NULL, NULL, qstr, tu, exz, aux_o, e_rate, ql, rid, khit);
        
        // fprintf(stderr, "-[M::%s::aln_ol->%lu] utg%.6dl(%c), align::%u, q::[%u, %u), t::[%u, %u)\n", __func__, aln_ol,
        //         (int32_t)z->y_id + 1, "+-"[z->y_pos_strand], z->align_length,
        //         z->x_pos_s, z->x_pos_e+1, z->y_pos_s, z->y_pos_e+1);
        // print_aln_windows(z);


        rln->n = rln_0;
        cn = ((uint32_t)(ct->idx.a[z->y_id])); 
        ca = ct->rids.a + ((ct->idx.a[z->y_id])>>32);
        gen_sub_ov_adv_cigar(udb, z, qstr, tu, exz, ql, o_rate, e_rate, NULL, 0, rid, oid, trace, rln);
        gen_sub_ov_adv_cigar(udb, z, qstr, tu, exz, ql, o_rate, e_rate, ca, cn, rid, oid, trace, cln);
        return 1;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movapd %xmm1, %xmm2
movq %rdx, %r12
movq %rdi, %rbx
movq 0x148(%rsp), %r13
movq 0x108(%rsp), %r15
movq 0x100(%rsp), %rdx
testq %r13, %r13
je 0x4f0ae
movl 0x28(%rbx), %eax
cmpq %r15, %rax
jbe 0x4f23d
movq %rsi, 0xa0(%rsp)
movq %rdx, 0x60(%rsp)
movq %r8, 0x68(%rsp)
movq %rcx, 0x80(%rsp)
movq %r9, 0x88(%rsp)
movsd %xmm0, 0x70(%rsp)
movq 0x140(%rsp), %rcx
movq %rcx, 0x98(%rsp)
movq 0x138(%rsp), %rcx
movq %rcx, 0xc0(%rsp)
movq 0x128(%rsp), %rcx
movq %rcx, 0x78(%rsp)
movq 0x120(%rsp), %rcx
movq %rcx, 0xb8(%rsp)
movq 0x118(%rsp), %rcx
movq %rcx, 0xb0(%rsp)
movq 0x110(%rsp), %rbp
movq 0x20(%r12), %rdx
movl 0x8(%rbx), %ecx
subl 0x4(%rbx), %ecx
incl %ecx
movq 0x8(%rbp), %r14
cvtsi2sd %rcx, %xmm0
mulsd %xmm2, %xmm0
movl %eax, %eax
cvtsi2sd %rax, %xmm1
ucomisd %xmm0, %xmm1
movsd %xmm2, 0x50(%rsp)
movq %rdx, 0xa8(%rsp)
jae 0x4f134
movq 0x10(%rdx), %rax
movl 0x10(%rbx), %ecx
movq (%rax,%rcx,8), %rax
movl %eax, %ecx
movq %rcx, 0x58(%rsp)
shrq $0x20, %rax
movq %r14, %r15
imulq $0xc, %rax, %r14
addq 0x28(%rdx), %r14
movq %r12, %rdi
movq %rbx, %rsi
movapd %xmm2, %xmm0
xorl %edx, %edx
xorl %ecx, %ecx
movq %rbp, %r8
callq 0x49d50
movq %r12, %rdi
movq %rbx, %rsi
movsd 0x50(%rsp), %xmm0
movq %r14, %rdx
movq %r15, %r14
movq 0x58(%rsp), %rcx
movq %rbp, %r8
callq 0x49d50
jmp 0x4f1b7
movq (%r8), %r8
movq %rdx, (%rsp)
movq $0x1, 0x8(%rsp)
movsd 0x1944ba(%rip), %xmm1   # 0x1e3580
movq %rbx, %rdi
movq %r12, %rsi
xorl %edx, %edx
movsd %xmm2, 0x50(%rsp)
callq 0x2b6ed
movsd 0x50(%rsp), %xmm0
movl 0x8(%rbx), %ecx
movl 0x28(%rbx), %eax
subl 0x4(%rbx), %ecx
incl %ecx
cvtsi2sd %rax, %xmm2
cvtsi2sd %rcx, %xmm1
mulsd %xmm0, %xmm1
ucomisd %xmm1, %xmm2
jae 0x4f3ae
cmpq %r15, %rax
jbe 0x4f23d
movq 0x48(%rbx), %rsi
movq 0x58(%rbx), %rdi
mulsd 0x19442d(%rip), %xmm0   # 0x1e3548
movq %r15, %rdx
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4eca2
movq (%rbp), %rax
cmpq 0x10(%rbp), %r14
jne 0x4f166
leaq (%r14,%r14), %rcx
testq %r14, %r14
pushq $0x2
popq %rdx
cmovneq %rcx, %rdx
movq %rdx, 0x10(%rbp)
imulq $0x1c, %rdx, %rsi
movq %rax, %rdi
callq 0x2370
movq %rax, (%rbp)
movq 0x8(%rbp), %rcx
jmp 0x4f169
movq %r14, %rcx
leaq 0x1(%rcx), %rdx
movq %rdx, 0x8(%rbp)
imulq $0x1c, %rcx, %rcx
xorpd %xmm0, %xmm0
movupd %xmm0, 0xc(%rax,%rcx)
movupd %xmm0, (%rax,%rcx)
movl 0x14(%rbx), %edx
movl %edx, 0x10(%rax,%rcx)
movl 0x18(%rbx), %edx
incl %edx
movl %edx, 0x14(%rax,%rcx)
movl 0x4(%rbx), %edx
movl %edx, 0x4(%rax,%rcx)
movl 0x8(%rbx), %edx
incl %edx
movl %edx, 0x8(%rax,%rcx)
movl 0x1c(%rbx), %edx
shll $0x1f, %edx
movl %edx, 0x18(%rax,%rcx)
orl $-0x1, (%rax,%rcx)
orl $-0x1, 0xc(%rax,%rcx)
movq 0x8(%rbp), %rax
cmpq %r14, %rax
jbe 0x4f23d
movq (%rbp), %rcx
imulq $0x1c, %r14, %r15
leaq (%rcx,%r15), %rdi
imulq $0x1c, %rax, %rsi
addq %rcx, %rsi
callq 0x1a7a0
movq %r15, 0x58(%rsp)
leaq 0x8(%r15), %rax
xorl %esi, %esi
movq %r14, %rdx
movq %r14, %rcx
cmpq 0x8(%rbp), %rdx
jae 0x4f244
movq (%rbp), %rdi
testq %rsi, %rsi
je 0x4f210
movl 0x8(%rsi), %r8d
cmpl %r8d, -0x4(%rdi,%rax)
jae 0x4f210
movl (%rdi,%rax), %edi
cmpl %r8d, %edi
jbe 0x4f234
movl %edi, 0x8(%rsi)
jmp 0x4f234
imulq $0x1c, %rcx, %r8
incq %rcx
leaq (%rdi,%r8), %rsi
movupd -0x8(%rdi,%rax), %xmm0
movupd 0x4(%rdi,%rax), %xmm1
movupd %xmm1, 0xc(%rdi,%r8)
movupd %xmm0, (%rdi,%r8)
incq %rdx
addq $0x1c, %rax
jmp 0x4f1e9
xorl %eax, %eax
jmp 0x4f3b1
movq %rcx, 0x8(%rbp)
movq %rbx, %rdi
movq 0xa0(%rsp), %r15
movq %r15, %rsi
callq 0x4a008
movq 0x58(%rsp), %rdx
addq (%rbp), %rdx
movq 0x8(%rbp), %rcx
subq %r14, %rcx
movq 0x98(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x78(%rsp), %rax
movq %rax, 0x30(%rsp)
movq %r13, 0x28(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x68(%rsp), %rax
movq %rax, 0x18(%rsp)
movq %r14, %r13
movq 0x80(%rsp), %r14
movq %r14, 0x10(%rsp)
xorpd %xmm0, %xmm0
movupd %xmm0, (%rsp)
movq %rbx, %rdi
movq %r15, %rsi
movq 0x60(%rsp), %r8
movq %r12, %r9
movsd 0x70(%rsp), %xmm0
callq 0x39034
movq %r13, 0x8(%rbp)
movq 0xa8(%rsp), %rdx
movq 0x10(%rdx), %rax
movl 0x10(%rbx), %ecx
movq (%rax,%rcx,8), %rax
movl %eax, %ecx
movq %rcx, 0x60(%rsp)
shrq $0x20, %rax
imulq $0xc, %rax, %r15
addq 0x28(%rdx), %r15
movq %rbp, 0x28(%rsp)
movq %r12, %rdi
movq %r12, 0x90(%rsp)
movq 0xb8(%rsp), %r12
movq %r12, 0x20(%rsp)
movq 0xc0(%rsp), %rbp
movq %rbp, 0x18(%rsp)
xorps %xmm0, %xmm0
movups %xmm0, (%rsp)
movq %rbx, %rsi
movq %r14, %rdx
movq 0x68(%rsp), %rcx
movq 0x88(%rsp), %r13
movq %r13, %r8
movq 0x78(%rsp), %r14
movq %r14, %r9
movsd 0x50(%rsp), %xmm0
movsd 0x70(%rsp), %xmm1
callq 0x4e730
movq 0xb0(%rsp), %rax
movq %rax, 0x28(%rsp)
movq %r12, 0x20(%rsp)
movq %rbp, 0x18(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x8(%rsp)
movq %r15, (%rsp)
movq 0x90(%rsp), %rdi
movq %rbx, %rsi
movq 0x80(%rsp), %rdx
movq 0x68(%rsp), %rcx
movq %r13, %r8
movq %r14, %r9
movsd 0x50(%rsp), %xmm0
movsd 0x70(%rsp), %xmm1
callq 0x4e730
pushq $0x1
popq %rax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq