// File: chhylp123[P]hifiasm/Purge_Dups.cpp
// Function: get_read_peak(asg_t*, long long*, long long, long long*, long long*, long long*, long long*, long long*, long long)
void get_read_peak(asg_t *read_g, long long* cov_buf, long long cov_buf_length, long long* topo_peak_cov, 
long long* hom_peak, long long* het_peak, long long* k_mer_only, long long* coverage_only, long long g_size)
{
    long long i, start, err_i, max_i, max2_i, max3_i, topo_peak_i, max, max2, max3, topo_peak, min;

    i = start = err_i = max_i = max2_i = max3_i = topo_peak_i = -1;
    max = max2 = max3 = topo_peak = min = -1;

    ///cov_buf[0] is usually very large
    for (i = 1; i < cov_buf_length; ++i)
    {
        if(cov_buf[i] > cov_buf[i-1]) break;
    }
    err_i = i - 1;
    // find the global highest peak
	max_i = err_i + 1, max = cov_buf[max_i];
    for (i = max_i; i < cov_buf_length; ++i)
    {
        if (cov_buf[i] > max)
        {
            max = cov_buf[i];
            max_i = i;
        }
    }

    ///print_peak(cov_buf, cov_buf_length, max_i);

    // look for smaller peak on the low end
	max2 = -1; max2_i = -1;
	for (i = max_i - 1; i > err_i; --i) 
    {
		///at first, it should be a peak
		if (cov_buf[i] >= cov_buf[i-1] && cov_buf[i] >= cov_buf[i+1]) 
        {
			if (cov_buf[i] > max2)
            {
                max2 = cov_buf[i];
                max2_i = i;
            } 
		}
	}

    ///fprintf(stderr, "***max2: %lld, max2_i: %lld\n", max2, max2_i);

    if (max2_i != -1 && max2_i > err_i && max2_i < max_i) 
    {
		for (i = max2_i + 1, min = max; i < max_i; ++i)
        {
            if (cov_buf[i] < min) min = cov_buf[i];
        }
			
		///if the second peak is not significant
		if(max2 < max * 0.05 || min > max2 * 0.95) max2 = max2_i = -1;
	}
    if(max2 < max*0.0075) max2 = max2_i = -1;
		

    // look for smaller peak on the high end
	max3 = -1; max3_i = -1;
    // we'd better use i < cov_buf_length - 1, since cov_buf[cov_buf_length-1] may have problem
	for (i = max_i + 1; i < cov_buf_length - 1; ++i) 
    {
		//at first, it should be a peak
		if (cov_buf[i] >= cov_buf[i-1] && cov_buf[i] >= cov_buf[i+1]) 
        {
			if (cov_buf[i] > max3)
            {
                max3 = cov_buf[i], max3_i = i;
            } 
		}
	}

    ///fprintf(stderr, "***max3: %lld, max3_i: %lld\n", max3, max3_i);
    
    //if found a peak
	if (max3 != -1 && max3_i > max_i) 
    {
		for (i = max_i + 1, min = max; i < max3_i; ++i)
        {
            if (cov_buf[i] < min) min = cov_buf[i];
        }
			
		if (max3 < max * 0.05 || min > max3 * 0.95 || max3_i > max_i * 3) max3 = max3_i = -1;
	}
    if (max3 < max*0.0075) max3 = max3_i = -1;

    

    (*hom_peak) = (*het_peak) = -1;
    if (topo_peak_cov && (*topo_peak_cov) < cov_buf_length)
    {
        topo_peak_i = (*topo_peak_cov);
        topo_peak = cov_buf[topo_peak_i];
        if (topo_peak <= max * 0.05) topo_peak_i = topo_peak = -1;
    }

    if(asm_opt.purge_level_primary == 0) 
    {
        (*hom_peak) = max_i;
        return;
    }
    
    
    long long k_mer_het, k_mer_hom, coverage_het, coverage_hom, alter_peak;
    k_mer_het = k_mer_hom = coverage_het = coverage_hom = alter_peak = -1;

    alter_peak = topo_peak_i;
    k_mer_het = asm_opt.het_cov;
    k_mer_hom = asm_opt.hom_cov;
    if(max3_i > 0)
    {
        coverage_het = max_i;
        coverage_hom = max3_i;
    }
    else
    {
        coverage_het = max2_i;
        coverage_hom = max_i;
    }

    if(g_size > 0) {
        long long n_bs, m_peak_hom = -1;
        int p_ht = -1;
        for (i = n_bs = 0; i < read_g->n_seq; i++) n_bs += read_g->seq[i].len;
        m_peak_hom = n_bs/g_size;
        if(m_peak_hom > 0) {
            p_ht = -1;
            coverage_hom = adj_m_peak_hom(m_peak_hom, max_i, max2_i, max3_i, &p_ht);
            coverage_het = p_ht;
        }   
    }

    if(k_mer_het != -1)
    {
        (*het_peak) = k_mer_het;
        (*hom_peak) = k_mer_hom;
        return;
    }
    else if(coverage_het != -1)
    {
        (*het_peak) = coverage_het;
        (*hom_peak) = coverage_hom;
        return;
    }
    else if(k_mer_hom > coverage_hom*1.5)
    {
        (*het_peak) = coverage_hom;
        (*hom_peak) = k_mer_hom;
        return;
    }
    else if(alter_peak != -1)
    {
        ///if peak is het, coverage peak is more reliable 
        if(coverage_hom >= alter_peak*0.8 && coverage_hom <= alter_peak*1.2) 
        {
            (*het_peak) = coverage_hom;
            return;
        }///if peak is homo, k-mer peak is more reliable 
        else if(k_mer_hom >= alter_peak*0.8*2 && k_mer_hom <= alter_peak*1.2*2)
        {
            (*hom_peak) = k_mer_hom;
            return;
        }
    }

    (*k_mer_only) = k_mer_hom;
    (*coverage_only) = coverage_hom;
    

    // fprintf(stderr, "max: %lld, max_i: %lld\n", max, max_i);
    // fprintf(stderr, "max2: %lld, max2_i: %lld\n", max2, max2_i);
    // fprintf(stderr, "max3: %lld, max3_i: %lld\n", max3, max3_i);
    // fprintf(stderr, "[M::%s] Heterozygous k-mer peak: %d\n", __func__, asm_opt.het_cov);
    // fprintf(stderr, "[M::%s] Homozygous k-mer peak: %d\n", __func__, asm_opt.hom_cov);
    // fprintf(stderr, "[M::%s] Heterozygous coverage peak: %lld\n", __func__, (*het_peak));
    // fprintf(stderr, "[M::%s] Homozygous coverage peak: %lld\n", __func__, (*hom_peak));
    // fprintf(stderr, "[M::%s] Alter coverage peak: %lld\n", __func__, topo_peak_i);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq $-0x1, -0x68(%rbp)
movq $-0x1, -0x60(%rbp)
movq $-0x1, -0x58(%rbp)
movq $-0x1, -0x50(%rbp)
movq $-0x1, -0x48(%rbp)
movq $-0x1, -0x40(%rbp)
movq $-0x1, -0x38(%rbp)
movq $-0x1, -0x90(%rbp)
movq $-0x1, -0x88(%rbp)
movq $-0x1, -0x80(%rbp)
movq $-0x1, -0x78(%rbp)
movq $-0x1, -0x70(%rbp)
movq $0x1, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x18(%rbp), %rax
jge 0x16e9c7
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq -0x10(%rbp), %rcx
movq -0x38(%rbp), %rdx
subq $0x1, %rdx
cmpq (%rcx,%rdx,8), %rax
jle 0x16e9b7
jmp 0x16e9c7
jmp 0x16e9b9
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x16e98d
movq -0x38(%rbp), %rax
subq $0x1, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rax
movq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x70(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x18(%rbp), %rax
jge 0x16ea3b
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpq -0x70(%rbp), %rax
jle 0x16ea2b
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x70(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x50(%rbp)
jmp 0x16ea2d
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x16e9f7
movq $-0x1, -0x78(%rbp)
movq $-0x1, -0x58(%rbp)
movq -0x50(%rbp), %rax
subq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x48(%rbp), %rax
jle 0x16ead6
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq -0x10(%rbp), %rcx
movq -0x38(%rbp), %rdx
subq $0x1, %rdx
cmpq (%rcx,%rdx,8), %rax
jl 0x16eac6
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq -0x10(%rbp), %rcx
movq -0x38(%rbp), %rdx
cmpq 0x8(%rcx,%rdx,8), %rax
jl 0x16eac6
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpq -0x78(%rbp), %rax
jle 0x16eac4
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x78(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x16eac6
jmp 0x16eac8
movq -0x38(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x16ea57
cmpq $-0x1, -0x58(%rbp)
je 0x16eba7
movq -0x58(%rbp), %rax
cmpq -0x48(%rbp), %rax
jle 0x16eba7
movq -0x58(%rbp), %rax
cmpq -0x50(%rbp), %rax
jge 0x16eba7
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x50(%rbp), %rax
jge 0x16eb56
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpq -0x90(%rbp), %rax
jge 0x16eb46
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x90(%rbp)
jmp 0x16eb48
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x16eb14
cvtsi2sdq -0x78(%rbp), %xmm1
cvtsi2sdq -0x70(%rbp), %xmm0
movsd 0x2136d6(%rip), %xmm2   # 0x382240
mulsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
ja 0x16eb95
cvtsi2sdq -0x90(%rbp), %xmm0
cvtsi2sdq -0x78(%rbp), %xmm1
movsd 0x213695(%rip), %xmm2   # 0x382220
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x16eba5
movq $-0x1, -0x58(%rbp)
movq $-0x1, -0x78(%rbp)
jmp 0x16eba7
cvtsi2sdq -0x78(%rbp), %xmm1
cvtsi2sdq -0x70(%rbp), %xmm0
movsd 0x21b6ed(%rip), %xmm2   # 0x38a2a8
mulsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jbe 0x16ebd5
movq $-0x1, -0x58(%rbp)
movq $-0x1, -0x78(%rbp)
movq $-0x1, -0x80(%rbp)
movq $-0x1, -0x60(%rbp)
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x18(%rbp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jge 0x16ec7a
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq -0x10(%rbp), %rcx
movq -0x38(%rbp), %rdx
subq $0x1, %rdx
cmpq (%rcx,%rdx,8), %rax
jl 0x16ec67
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq -0x10(%rbp), %rcx
movq -0x38(%rbp), %rdx
cmpq 0x8(%rcx,%rdx,8), %rax
jl 0x16ec67
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpq -0x80(%rbp), %rax
jle 0x16ec65
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x80(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x16ec67
jmp 0x16ec69
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x16ebf1
cmpq $-0x1, -0x80(%rbp)
je 0x16ed4b
movq -0x60(%rbp), %rax
cmpq -0x50(%rbp), %rax
jle 0x16ed4b
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x60(%rbp), %rax
jge 0x16ecec
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpq -0x90(%rbp), %rax
jge 0x16ecdc
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x90(%rbp)
jmp 0x16ecde
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x16ecaa
cvtsi2sdq -0x80(%rbp), %xmm1
cvtsi2sdq -0x70(%rbp), %xmm0
movsd 0x213540(%rip), %xmm2   # 0x382240
mulsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
ja 0x16ed39
cvtsi2sdq -0x90(%rbp), %xmm0
cvtsi2sdq -0x80(%rbp), %xmm1
movsd 0x2134ff(%rip), %xmm2   # 0x382220
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
ja 0x16ed39
movq -0x60(%rbp), %rax
imulq $0x3, -0x50(%rbp), %rcx
cmpq %rcx, %rax
jle 0x16ed49
movq $-0x1, -0x60(%rbp)
movq $-0x1, -0x80(%rbp)
jmp 0x16ed4b
cvtsi2sdq -0x80(%rbp), %xmm1
cvtsi2sdq -0x70(%rbp), %xmm0
movsd 0x21b549(%rip), %xmm2   # 0x38a2a8
mulsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jbe 0x16ed79
movq $-0x1, -0x60(%rbp)
movq $-0x1, -0x80(%rbp)
movq -0x30(%rbp), %rax
movq $-0x1, (%rax)
movq -0x28(%rbp), %rax
movq $-0x1, (%rax)
cmpq $0x0, -0x20(%rbp)
je 0x16edf7
movq -0x20(%rbp), %rax
movq (%rax), %rax
cmpq -0x18(%rbp), %rax
jge 0x16edf7
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rax
movq -0x68(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x88(%rbp)
cvtsi2sdq -0x88(%rbp), %xmm1
cvtsi2sdq -0x70(%rbp), %xmm0
movsd 0x213468(%rip), %xmm2   # 0x382240
mulsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jb 0x16edf5
movq $-0x1, -0x88(%rbp)
movq $-0x1, -0x68(%rbp)
jmp 0x16edf7
leaq 0x2559fa(%rip), %rax    # 0x3c47f8
cmpl $0x0, 0x130(%rax)
jne 0x16ee17
movq -0x50(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
jmp 0x16f137
movq $-0x1, -0xb8(%rbp)
movq $-0x1, -0xb0(%rbp)
movq $-0x1, -0xa8(%rbp)
movq $-0x1, -0xa0(%rbp)
movq $-0x1, -0x98(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0xb8(%rbp)
leaq 0x255998(%rip), %rax    # 0x3c47f8
movslq 0xd4(%rax), %rax
movq %rax, -0x98(%rbp)
leaq 0x255983(%rip), %rax    # 0x3c47f8
movslq 0xd0(%rax), %rax
movq %rax, -0xa0(%rbp)
cmpq $0x0, -0x60(%rbp)
jle 0x16eea2
movq -0x50(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0xb0(%rbp)
jmp 0x16eeb8
movq -0x58(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0xb0(%rbp)
cmpq $0x0, 0x20(%rbp)
jle 0x16ef9d
movq $-0x1, -0xc8(%rbp)
movl $0xffffffff, -0xcc(%rbp) # imm = 0xFFFFFFFF
movq $0x0, -0xc0(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x8(%rbp), %rcx
movl 0x14(%rcx), %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
movl %ecx, %ecx
cmpq %rcx, %rax
jge 0x16ef35
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x38(%rbp), %rcx
movl (%rax,%rcx,8), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movl %eax, %eax
addq -0xc0(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x16eeeb
movq -0xc0(%rbp), %rax
cqto
idivq 0x20(%rbp)
movq %rax, -0xc8(%rbp)
cmpq $0x0, -0xc8(%rbp)
jle 0x16ef9b
movl $0xffffffff, -0xcc(%rbp) # imm = 0xFFFFFFFF
movq -0xc8(%rbp), %rax
movl %eax, %edi
movq -0x50(%rbp), %rax
movl %eax, %esi
movq -0x58(%rbp), %rax
movl %eax, %edx
movq -0x60(%rbp), %rax
movl %eax, %ecx
leaq -0xcc(%rbp), %r8
callq 0x192410
cltq
movq %rax, -0xb0(%rbp)
movslq -0xcc(%rbp), %rax
movq %rax, -0xa8(%rbp)
jmp 0x16ef9d
cmpq $-0x1, -0x98(%rbp)
je 0x16efc8
movq -0x98(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0xa0(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
jmp 0x16f137
cmpq $-0x1, -0xa8(%rbp)
je 0x16eff3
movq -0xa8(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0xb0(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
jmp 0x16f137
cvtsi2sdq -0xa0(%rbp), %xmm0
cvtsi2sdq -0xb0(%rbp), %xmm1
movsd 0x2131f3(%rip), %xmm2   # 0x382200
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x16f038
movq -0xb0(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0xa0(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
jmp 0x16f137
cmpq $-0x1, -0xb8(%rbp)
je 0x16f115
cvtsi2sdq -0xb0(%rbp), %xmm0
cvtsi2sdq -0xb8(%rbp), %xmm1
movsd 0x2131d0(%rip), %xmm2   # 0x382230
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jb 0x16f0a1
cvtsi2sdq -0xb0(%rbp), %xmm1
cvtsi2sdq -0xb8(%rbp), %xmm0
movsd 0x21322c(%rip), %xmm2   # 0x3822b0
mulsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jb 0x16f0a1
movq -0xb0(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
jmp 0x16f137
cvtsi2sdq -0xa0(%rbp), %xmm0
cvtsi2sdq -0xb8(%rbp), %xmm1
movsd 0x213175(%rip), %xmm2   # 0x382230
mulsd %xmm2, %xmm1
movsd 0x213221(%rip), %xmm2   # 0x3822e8
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jb 0x16f111
cvtsi2sdq -0xa0(%rbp), %xmm1
cvtsi2sdq -0xb8(%rbp), %xmm0
movsd 0x2131c5(%rip), %xmm2   # 0x3822b0
mulsd %xmm2, %xmm0
movsd 0x2131f1(%rip), %xmm2   # 0x3822e8
mulsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jb 0x16f111
movq -0xa0(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
jmp 0x16f137
jmp 0x16f113
jmp 0x16f115
jmp 0x16f117
jmp 0x16f119
jmp 0x16f11b
movq -0xa0(%rbp), %rcx
movq 0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0xb0(%rbp), %rcx
movq 0x18(%rbp), %rax
movq %rcx, (%rax)
addq $0xd0, %rsp
popq %rbp
retq