// File: /workspace/github_c_makefile_star2_O0/c-zhou[P]oatk/syncasm.c
// Function: scg_consensus
void scg_consensus(sr_db_t *sr_db, scg_t *scg, int hoco_seq, int save_seq, FILE *fo)
{
    uint64_t i, v, t, z, n;
    int64_t l;
    double cov;
    int w;
    syncmer_t *scm;
    asmg_t *utg_asmg;
    asmg_arc_t *a;
    scg_utg_t *s;
    kstring_t c_seq = {0, 0, 0};
#ifdef DEBUG_CONSENSUS
    uint64_t j;
    int64_t l1;
    kstring_t c_seq1 = {0, 0, 0};
#endif

    w = sr_db->k;
    scm = scg_a_scm(scg);
    utg_asmg = scg->utg_asmg;
    asmg_clean_consensus(utg_asmg); // clean consensus sequences
    
    if (fo) fprintf(fo, "H\tVN:Z:1.0\n");
    for (i = 0, n = utg_asmg->n_vtx; i < n; ++i) {
        s = &utg_asmg->vtx[i];
        if (s->del) continue;
        c_seq.l = 0;
        l = scg_unitig_consensus(sr_db, s->a, s->n, scm, &c_seq, hoco_seq);
#ifdef DEBUG_CONSENSUS
        scg_utg_t s1 = {s->n, 0, 0, s->len, s->cov, s->del, s->circ};
        MYMALLOC(s1.a, s1.n);
        for (j = 0; j < s1.n; ++j) s1.a[s1.n-1-j] = s->a[j]^1;
        c_seq1.l = 0;
        l1 = scg_unitig_consensus(sr_db, s1.a, s1.n, scm, &c_seq1, hoco_seq);
        str_reverse_complement(c_seq1.s, c_seq1.l);
        if (l1 != l || strncmp(c_seq.s, c_seq1.s, l)) {
            fprintf(stderr, "[DEBUG_CONSENSUS::%s] different forward backward consensus sequences: u%lu [%ld %ld] %.*s %.*s\n",
                    __func__, i, l, l1, (int) l, c_seq.s, (int) l1, c_seq1.s);
        }
        free(s1.a);
#endif
        cov = s->cov? s->cov : utg_avg_cov(scg, s);
        s->cov = cov;
        s->len = l;
        if (save_seq) {
            if (s->seq) free(s->seq);
            MYMALLOC(s->seq, l+1);
            strncpy(s->seq, c_seq.s, l);
            s->seq[l] = 0;
        }
        if (fo) fprintf(fo, "S\tu%lu\t%.*s\tLN:i:%ld\tKC:i:%ld\tSC:f:%.3f\n", i, (int) l, c_seq.s, l, (int64_t) (l*cov), cov);

#ifdef DEBUG_UTG_COVERAGE
        uint64_t j;
        fprintf(stderr, "[DEBUG_UTG_COVERAGE::%s] u%lu [N=%lu]:", __func__, i, s->n);
        for (j = 0; j < s->n; ++j) fprintf(stderr, " s%lu%c", s->a[j]>>1, "+-"[s->a[j]&1]);
        fputc('\n', stderr);
        fprintf(stderr, "[DEBUG_UTG_COVERAGE::%s] u%lu [N=%lu]:", __func__, i, s->n);
        for (j = 0; j < s->n; ++j) fprintf(stderr, " %u", scm[s->a[j]>>1].cov);
        fputc('\n', stderr);
#endif
    }

    for (i = 0, n = utg_asmg->n_arc; i < n; ++i) {
        a = &utg_asmg->arc[i];
        if (a->del || a->comp) continue;
        
        if (a->ln > 0) {
            // need to calculate the consensus length of the overlaping syncmers
            s = &utg_asmg->vtx[a->v>>1];
            c_seq.l = 0;
            l = scg_unitig_consensus(sr_db, (a->v&1)? s->a : &s->a[s->n - a->ln], a->ln, scm, &c_seq, hoco_seq);
#ifdef DEBUG_CONSENSUS
            fprintf(stderr, "[DEBUG_CONSENSUS::%s] syncmer overlap (ln=%lu) for arc u%lu%c->u%lu%c v_n=%lu v_s=%lu\n", 
                    __func__, a->ln, a->v>>1, "+-"[a->v&1], a->w>>1, "+-"[a->w&1], s->n, (a->v&1)? 0 : s->n - a->ln);
#endif
        } else {
            // need to calculate the consensus overlap between the two end syncmers
            s = &utg_asmg->vtx[a->v>>1];
            z = a->v&1;
            v = s->a[(s->n-1) * (!z)]^z;
            s = &utg_asmg->vtx[a->w>>1];
            z = a->w&1;
            t = s->a[(s->n-1) * z]^z;
            l = calc_syncmer_overlap(sr_db, &scm[v>>1], v&1, &scm[t>>1], t&1, 0);
            if (l < w) {
                c_seq.l = 0;
                l = scg_syncmer_consensus(sr_db, &scm[v>>1], v&1, l, &c_seq, hoco_seq);
            } else {
                l = 0;
            }
        }
        // FIXME: consensus problem seql < lo
        l = MIN((uint64_t) l, utg_asmg->vtx[a->v>>1].len);
        l = MIN((uint64_t) l, utg_asmg->vtx[a->w>>1].len);
        a->ls = l;
        asmg_arc(utg_asmg, a->w^1, a->v^1)->ls = l;
        if (fo) {
            fprintf(fo, "L\tu%lu\t%c\tu%lu\t%c\t%ldM\tEC:i:%u\n", a->v>>1, "+-"[a->v&1], a->w>>1, "+-"[a->w&1], l, a->cov);
            fprintf(fo, "L\tu%lu\t%c\tu%lu\t%c\t%ldM\tEC:i:%u\n", a->w>>1, "-+"[a->w&1], a->v>>1, "-+"[a->v&1], l, a->cov);
        }
    }
    
    free(c_seq.s);
#ifdef DEBUG_CONSENSUS
    free(c_seq1.s);
#endif
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movq %r8, -0x20(%rbp)
leaq -0x98(%rbp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x21f0
movq -0x8(%rbp), %rax
movl 0x18(%rax), %eax
movl %eax, -0x5c(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rdi
callq 0x5f20
cmpq $0x0, -0x20(%rbp)
je 0x58e7
movq -0x20(%rbp), %rdi
leaq 0x27fe1(%rip), %rsi     # 0x2d8c1
movb $0x0, %al
callq 0x2290
movq $0x0, -0x28(%rbp)
movq -0x70(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x28(%rbp), %rax
cmpq -0x48(%rbp), %rax
jae 0x5a9e
movq -0x70(%rbp), %rax
movq 0x10(%rax), %rax
imulq $0x28, -0x28(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movl 0x20(%rax), %eax
shrl $0x1e, %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x5933
jmp 0x5a8d
movq $0x0, -0x98(%rbp)
movq -0x8(%rbp), %rdi
movq -0x80(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x80(%rbp), %rax
movq (%rax), %rdx
movq -0x68(%rbp), %rcx
movl -0x14(%rbp), %r9d
leaq -0x98(%rbp), %r8
callq 0x6010
movq %rax, -0x50(%rbp)
movq -0x80(%rbp), %rax
movl 0x20(%rax), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
cmpl $0x0, %eax
je 0x5994
movq -0x80(%rbp), %rax
movl 0x20(%rax), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0xa0(%rbp)
jmp 0x59a9
movq -0x10(%rbp), %rdi
movq -0x80(%rbp), %rsi
callq 0x5630
movsd %xmm0, -0xa0(%rbp)
movsd -0xa0(%rbp), %xmm0
movsd %xmm0, -0x58(%rbp)
cvttsd2si -0x58(%rbp), %rax
movl %eax, %edx
movq -0x80(%rbp), %rax
movl 0x20(%rax), %ecx
andl $0x3fffffff, %edx       # imm = 0x3FFFFFFF
andl $0xc0000000, %ecx       # imm = 0xC0000000
orl %edx, %ecx
movl %ecx, 0x20(%rax)
movq -0x50(%rbp), %rcx
movq -0x80(%rbp), %rax
movq %rcx, 0x18(%rax)
cmpl $0x0, -0x18(%rbp)
je 0x5a44
movq -0x80(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x5a00
movq -0x80(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x2060
movq -0x50(%rbp), %rdi
addq $0x1, %rdi
shlq $0x0, %rdi
callq 0x2320
movq %rax, %rcx
movq -0x80(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x80(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x88(%rbp), %rsi
movq -0x50(%rbp), %rdx
callq 0x2090
movq -0x80(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x50(%rbp), %rcx
movb $0x0, (%rax,%rcx)
cmpq $0x0, -0x20(%rbp)
je 0x5a8b
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rdx
movq -0x50(%rbp), %rax
movl %eax, %ecx
movq -0x88(%rbp), %r8
movq -0x50(%rbp), %r9
cvtsi2sdq -0x50(%rbp), %xmm0
mulsd -0x58(%rbp), %xmm0
cvttsd2si %xmm0, %rax
movsd -0x58(%rbp), %xmm0
leaq 0x27e4d(%rip), %rsi     # 0x2d8cd
movq %rax, (%rsp)
movb $0x1, %al
callq 0x2290
jmp 0x5a8d
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x58fa
movq $0x0, -0x28(%rbp)
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x28(%rbp), %rax
cmpq -0x48(%rbp), %rax
jae 0x5f09
movq -0x70(%rbp), %rax
movq 0x28(%rax), %rax
imulq $0x30, -0x28(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movl 0x20(%rax), %eax
shrl $0x1e, %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x5af5
movq -0x78(%rbp), %rax
movl 0x20(%rax), %eax
shrl $0x1f, %eax
cmpl $0x0, %eax
je 0x5afa
jmp 0x5ef8
movq -0x78(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jbe 0x5bb6
movq -0x70(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x78(%rbp), %rcx
movq (%rcx), %rcx
shrq %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x80(%rbp)
movq $0x0, -0x98(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x78(%rbp), %rax
movq (%rax), %rax
andq $0x1, %rax
cmpq $0x0, %rax
je 0x5b5e
movq -0x80(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0xb0(%rbp)
jmp 0x5b83
movq -0x80(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x80(%rbp), %rcx
movq (%rcx), %rcx
movq -0x78(%rbp), %rdx
subq 0x10(%rdx), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0xb0(%rbp)
movq -0xa8(%rbp), %rdi
movq -0xb0(%rbp), %rsi
movq -0x78(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x68(%rbp), %rcx
movl -0x14(%rbp), %r9d
leaq -0x98(%rbp), %r8
callq 0x6010
movq %rax, -0x50(%rbp)
jmp 0x5d0f
movq -0x70(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x78(%rbp), %rcx
movq (%rcx), %rcx
shrq %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x80(%rbp)
movq -0x78(%rbp), %rax
movq (%rax), %rax
andq $0x1, %rax
movq %rax, -0x40(%rbp)
movq -0x80(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x80(%rbp), %rcx
movq (%rcx), %rcx
subq $0x1, %rcx
cmpq $0x0, -0x40(%rbp)
setne %dl
xorb $-0x1, %dl
andb $0x1, %dl
movzbl %dl, %edx
movslq %edx, %rdx
imulq %rdx, %rcx
movq (%rax,%rcx,8), %rax
xorq -0x40(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x70(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x78(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x80(%rbp)
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rax
andq $0x1, %rax
movq %rax, -0x40(%rbp)
movq -0x80(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x80(%rbp), %rcx
movq (%rcx), %rcx
subq $0x1, %rcx
imulq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
xorq -0x40(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x30(%rbp), %rax
shrq %rax
shlq $0x5, %rax
addq %rax, %rsi
movq -0x30(%rbp), %rdx
andq $0x1, %rdx
movq -0x68(%rbp), %rcx
movq -0x38(%rbp), %rax
shrq %rax
shlq $0x5, %rax
addq %rax, %rcx
movq -0x38(%rbp), %r8
andq $0x1, %r8
xorl %eax, %eax
movl %eax, %r9d
callq 0x62a0
cltq
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movslq -0x5c(%rbp), %rcx
cmpq %rcx, %rax
jge 0x5d05
movq $0x0, -0x98(%rbp)
movq -0x8(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x30(%rbp), %rax
shrq %rax
shlq $0x5, %rax
addq %rax, %rsi
movq -0x30(%rbp), %rax
andq $0x1, %rax
movl %eax, %edx
movq -0x50(%rbp), %rcx
movl -0x14(%rbp), %r9d
leaq -0x98(%rbp), %r8
callq 0x6900
movq %rax, -0x50(%rbp)
jmp 0x5d0d
movq $0x0, -0x50(%rbp)
jmp 0x5d0f
movq -0x50(%rbp), %rax
movq -0x70(%rbp), %rcx
movq 0x10(%rcx), %rcx
movq -0x78(%rbp), %rdx
movq (%rdx), %rdx
shrq %rdx
imulq $0x28, %rdx, %rdx
addq %rdx, %rcx
cmpq 0x18(%rcx), %rax
jae 0x5d3f
movq -0x50(%rbp), %rax
movq %rax, -0xb8(%rbp)
jmp 0x5d63
movq -0x70(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x78(%rbp), %rcx
movq (%rcx), %rcx
shrq %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq 0x18(%rax), %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq -0x70(%rbp), %rcx
movq 0x10(%rcx), %rcx
movq -0x78(%rbp), %rdx
movq 0x8(%rdx), %rdx
shrq %rdx
imulq $0x28, %rdx, %rdx
addq %rdx, %rcx
cmpq 0x18(%rcx), %rax
jae 0x5d9f
movq -0x50(%rbp), %rax
movq %rax, -0xc0(%rbp)
jmp 0x5dc4
movq -0x70(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x78(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq 0x18(%rax), %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rcx
movq -0x78(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x50(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0x70(%rbp), %rdi
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rsi
xorq $0x1, %rsi
movq -0x78(%rbp), %rax
movq (%rax), %rdx
xorq $0x1, %rdx
callq 0x6f90
movq -0xc8(%rbp), %rcx
movq %rcx, 0x18(%rax)
cmpq $0x0, -0x20(%rbp)
je 0x5ef6
movq -0x20(%rbp), %rdi
movq -0x78(%rbp), %rax
movq (%rax), %rdx
shrq %rdx
movq -0x78(%rbp), %rax
movq (%rax), %rcx
andq $0x1, %rcx
leaq 0x27ada(%rip), %rax     # 0x2d916
movsbl (%rax,%rcx), %ecx
movq -0x78(%rbp), %rax
movq 0x8(%rax), %r8
shrq %r8
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rsi
andq $0x1, %rsi
leaq 0x27ab8(%rip), %rax     # 0x2d916
movsbl (%rax,%rsi), %r9d
movq -0x50(%rbp), %r10
movq -0x78(%rbp), %rax
movl 0x20(%rax), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
leaq 0x27a7c(%rip), %rsi     # 0x2d8f6
movq %r10, (%rsp)
movl %eax, 0x8(%rsp)
movb $0x0, %al
callq 0x2290
movq -0x20(%rbp), %rdi
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rdx
shrq %rdx
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rcx
andq $0x1, %rcx
leaq 0x27a6e(%rip), %rax     # 0x2d919
movsbl (%rax,%rcx), %ecx
movq -0x78(%rbp), %rax
movq (%rax), %r8
shrq %r8
movq -0x78(%rbp), %rax
movq (%rax), %rsi
andq $0x1, %rsi
leaq 0x27a4e(%rip), %rax     # 0x2d919
movsbl (%rax,%rsi), %r9d
movq -0x50(%rbp), %r10
movq -0x78(%rbp), %rax
movl 0x20(%rax), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
leaq 0x27a0f(%rip), %rsi     # 0x2d8f6
movq %r10, (%rsp)
movl %eax, 0x8(%rsp)
movb $0x0, %al
callq 0x2290
jmp 0x5ef8
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x5ab2
movq -0x88(%rbp), %rdi
callq 0x2060
addq $0xe0, %rsp
popq %rbp
retq
nop