// File: /workspace/github_cpp_makefile_star2_O2/schneebergerlab[P]DrLink/detect_recombsite.cpp
// Function: get_moleStat_distribution(char const*, double, int*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
bool get_moleStat_distribution(const char* file, 
                              double      maxPercent, 
                              int*        maxStat,
                              string      lenORreadnum)
{
    // this function finds out a cutoff for read_number/length of molecules for determining some of them as bad ones.
    // lenORreadnum is either "readNum" or "moleLen"
    cout << "   Info: checking " << lenORreadnum << " distribution ... " << endl;
    fstream fp;
    fp.open(file, ios::in);
    if(!fp.good())
    {
        cout << "   Error: cannot open read number distributio " << file << endl;
        return false;
    }
    vector<int>           xvalue;
    vector<unsigned long> yvalue;
    //
    int maxNumLen = 0; // if about length, in kb
    unsigned long maxcnt = 0;
    int xindex    = 0;
    int maxxindex = 0;
    char sepc = '\t';
    while(fp.good())
    {
        string line("");
        getline(fp, line);
        if(line.size()==0 || line[0]=='#') continue;
        
        if(sepc == '\t' && line.find("\t") == std::string::npos) 
        {
            sepc = ' ';
        }
        vector<string> lineinfo = split_string(line, sepc);
        if(line.size() < 2) continue;
        
        int           xxx = round(atof(lineinfo[0].c_str()));
        unsigned long yyy = strtoul(lineinfo[1].c_str(), NULL, 0);
        xindex ++;
        
        xvalue.push_back(xxx);
        yvalue.push_back(yyy);
        
        if(yyy > maxcnt)
        {
            maxcnt    = yyy;
            maxNumLen = xxx;
            maxxindex = xindex; // 1-based system; indeed ymax is at vector[maxxindex-1]
        }
    }
    // find a proper maximum statistic
    assert(maxxindex>=1);
    for(int i = maxxindex; i < xvalue.size(); i ++)
    {
        // caution: too stringent on molecule size
        if( (yvalue[i]*1.0)/(yvalue[maxxindex-1]*1.0)<maxPercent )
        {
            if(i == maxxindex)
            {
                // the one right next to max
                *maxStat = xvalue[i]; 
            }
            else
            {
                *maxStat = xvalue[i-1];
            }
            break;
        }
        else 
        if( lenORreadnum.compare("readNum")==0 && 
            (double)xvalue[i] > 1.5*(double)xvalue[maxxindex-1])
        {
            *maxStat = xvalue[i-1];
            break;
        }
        else 
        if( lenORreadnum.compare("moleLen")==0 && 
            (double)xvalue[i] > 1.5*(double)xvalue[maxxindex-1])
        {
            *maxStat = xvalue[i-1];
            break;
        }        
    }
    if(lenORreadnum.compare("readNum")==0)
    {
        *maxStat -= 1;
        cout << "   Info: maximum number of reads allowed for a good molecule: " 
             << *(maxStat)   << ";"    
             << endl;
        cout << "   Info: checking read number distribution done. "  
             << endl;
    }
    else
    if(lenORreadnum.compare("moleLen")==0)
    {
        *maxStat = (*maxStat) * 1000 + 1000; // into bp and complement 1kb: less stringent
        cout << "   Info: maximum length allowed for a good molecule: "          
             << *maxStat     
             << " bp;" 
             << endl;
        cout << "   Info: checking molecule length distribution done. "
             << endl;
    }   
    else
    {
        cout << "   Error: you should never reach here when checking readnum or length of molecules." 
             << endl;
        return false;
    } 
    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2b8, %rsp            # imm = 0x2B8
movq %rdx, %r12
movq %rsi, %r14
movsd %xmm0, 0x48(%rsp)
movq %rdi, %rbx
movq 0x2b595(%rip), %rdi     # 0x3cfc8
leaq 0x19e59(%rip), %rsi     # 0x2b893
callq 0x4330
movq %rax, %rdi
movq %r12, %rsi
callq 0x42e0
leaq 0x19e55(%rip), %rsi     # 0x2b8a6
movq %rax, %rdi
callq 0x4330
movq %rax, %rdi
callq 0x41c0
leaq 0xa8(%rsp), %r15
movq %r15, %rdi
callq 0x43a0
pushq $0x8
popq %rdx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x42f0
movq 0xa8(%rsp), %rax
movq -0x18(%rax), %rcx
cmpl $0x0, 0xc8(%rsp,%rcx)
je 0x11ac2
movq 0x2b52c(%rip), %rdi     # 0x3cfc8
leaq 0x19e16(%rip), %rsi     # 0x2b8b9
callq 0x4330
movq %rax, %rdi
movq %rbx, %rsi
callq 0x4330
movq %rax, %rdi
callq 0x41c0
xorl %ebx, %ebx
jmp 0x11e8e
movq %r12, 0x20(%rsp)
movq %r14, 0x8(%rsp)
xorpd %xmm0, %xmm0
leaq 0x30(%rsp), %rcx
movapd %xmm0, (%rcx)
andq $0x0, 0x10(%rcx)
leaq 0x50(%rsp), %rcx
movapd %xmm0, (%rcx)
andq $0x0, 0x10(%rcx)
leaq 0x3(%rsp), %r13
movb $0x9, (%r13)
movq $0x0, 0x18(%rsp)
leaq 0x1c014(%rip), %rbp     # 0x2db1a
leaq 0x88(%rsp), %rbx
leaq 0x70(%rsp), %r15
leaq 0xa8(%rsp), %r12
movl $0x0, 0x4(%rsp)
xorl %r14d, %r14d
movq -0x18(%rax), %rax
cmpl $0x0, 0xc8(%rsp,%rax)
jne 0x11c54
movq %rbx, %rdi
movq %rbp, %rsi
movq %r15, %rdx
callq 0x4d3e
movq %r12, %rdi
movq %rbx, %rsi
callq 0x4090
cmpq $0x0, 0x90(%rsp)
je 0x11c3f
movq 0x88(%rsp), %rax
cmpb $0x23, (%rax)
je 0x11c3f
cmpb $0x9, 0x3(%rsp)
jne 0x11b94
movq %rbx, %rdi
leaq 0x1bf97(%rip), %rsi     # 0x2db19
xorl %edx, %edx
callq 0x4600
cmpq $-0x1, %rax
jne 0x11b94
movb $0x20, 0x3(%rsp)
movq %r15, %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x26120
cmpq $0x2, 0x90(%rsp)
jb 0x11c37
movq %r12, %r15
movq %rbp, %r12
movq %r13, %rbp
movq 0x70(%rsp), %r13
movq (%r13), %rdi
callq 0x43d0
callq 0x4180
cvttsd2si %xmm0, %eax
movl %eax, 0x14(%rsp)
movq 0x20(%r13), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x4130
movq %rax, 0x28(%rsp)
leaq 0x30(%rsp), %rdi
leaq 0x14(%rsp), %rsi
callq 0x158a4
leaq 0x50(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x158c2
movl 0x4(%rsp), %edx
incl %edx
movq 0x28(%rsp), %rax
movq 0x18(%rsp), %rcx
cmpq %rcx, %rax
cmovaq %rax, %rcx
movq %rcx, 0x18(%rsp)
movl %edx, 0x4(%rsp)
cmoval %edx, %r14d
movq %rbp, %r13
movq %r12, %rbp
movq %r15, %r12
leaq 0x70(%rsp), %r15
movq %r15, %rdi
callq 0x5d02
movq %rbx, %rdi
callq 0x4638
movq 0xa8(%rsp), %rax
jmp 0x11b26
testl %r14d, %r14d
jle 0x11eaf
leal -0x1(%r14), %r12d
movl %r14d, %r14d
leaq (,%r14,4), %r13
negq %r13
xorl %ebp, %ebp
leaq 0x18e94(%rip), %r15     # 0x2ab0c
movq 0x20(%rsp), %rbx
movq 0x30(%rsp), %rax
movq 0x38(%rsp), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
cmpq %r14, %rcx
jbe 0x11d86
movq 0x50(%rsp), %rcx
movsd (%rcx,%r14,8), %xmm0
movsd 0x18416(%rip), %xmm2    # 0x2a0c0
unpcklps %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
movapd 0x1841b(%rip), %xmm3    # 0x2a0d0
subpd %xmm3, %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movsd (%rcx,%r12,8), %xmm0
unpcklps %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
subpd %xmm3, %xmm0
movapd %xmm0, %xmm2
unpckhpd %xmm0, %xmm2            # xmm2 = xmm2[1],xmm0[1]
addsd %xmm0, %xmm2
divsd %xmm2, %xmm1
movsd 0x48(%rsp), %xmm0
ucomisd %xmm1, %xmm0
ja 0x11d5c
movq %rbx, %rdi
leaq 0x18dea(%rip), %rsi     # 0x2aae2
callq 0x4110
testl %eax, %eax
jne 0x11d20
movq 0x30(%rsp), %rax
cvtsi2sdl (%rax,%r14,4), %xmm0
cvtsi2sdl (%rax,%r12,4), %xmm1
mulsd 0x18396(%rip), %xmm1    # 0x2a0b0
ucomisd %xmm1, %xmm0
ja 0x11d72
movq %rbx, %rdi
movq %r15, %rsi
callq 0x4110
testl %eax, %eax
jne 0x11d4e
movq 0x30(%rsp), %rax
cvtsi2sdl (%rax,%r14,4), %xmm0
cvtsi2sdl (%rax,%r12,4), %xmm1
mulsd 0x18368(%rip), %xmm1    # 0x2a0b0
ucomisd %xmm1, %xmm0
ja 0x11d72
incq %r14
decl %ebp
addq $-0x4, %r13
jmp 0x11c7d
movq %rax, %rcx
subq %r13, %rcx
testl %ebp, %ebp
movl %r14d, %edx
leaq -0x4(%rax,%rdx,4), %rax
cmoveq %rcx, %rax
jmp 0x11d7d
movl %r14d, %ecx
leaq (%rax,%rcx,4), %rax
addq $-0x4, %rax
movl (%rax), %eax
movq 0x8(%rsp), %rcx
movl %eax, (%rcx)
leaq 0x18d55(%rip), %rsi     # 0x2aae2
movq 0x20(%rsp), %rbx
movq %rbx, %rdi
callq 0x4110
testl %eax, %eax
je 0x11dd8
leaq 0x18d67(%rip), %rsi     # 0x2ab0c
movq %rbx, %rdi
callq 0x4110
testl %eax, %eax
movq 0x8(%rsp), %rbx
je 0x11e1c
movq 0x2b20b(%rip), %rdi     # 0x3cfc8
leaq 0x19c52(%rip), %rsi     # 0x2ba16
callq 0x4330
movq %rax, %rdi
callq 0x41c0
xorl %ebx, %ebx
jmp 0x11e7a
movq 0x8(%rsp), %rbx
decl (%rbx)
movq 0x2b1e2(%rip), %rdi     # 0x3cfc8
leaq 0x19b4c(%rip), %rsi     # 0x2b939
callq 0x4330
movl (%rbx), %esi
movq %rax, %rdi
callq 0x4580
leaq 0x195b7(%rip), %rsi     # 0x2b3ba
movq %rax, %rdi
callq 0x4330
movq %rax, %rdi
callq 0x41c0
leaq 0x19b5e(%rip), %rsi     # 0x2b978
jmp 0x11e64
imull $0x3e8, (%rbx), %eax    # imm = 0x3E8
addl $0x3e8, %eax            # imm = 0x3E8
movl %eax, (%rbx)
movq 0x2b198(%rip), %rdi     # 0x3cfc8
leaq 0x19b73(%rip), %rsi     # 0x2b9aa
callq 0x4330
movl (%rbx), %esi
movq %rax, %rdi
callq 0x4580
leaq 0x1956a(%rip), %rsi     # 0x2b3b7
movq %rax, %rdi
callq 0x4330
movq %rax, %rdi
callq 0x41c0
leaq 0x19b7c(%rip), %rsi     # 0x2b9e0
movq 0x2b15d(%rip), %rdi     # 0x3cfc8
callq 0x4330
movb $0x1, %bl
movq %rax, %rdi
callq 0x41c0
leaq 0x50(%rsp), %rdi
callq 0x17b7e
leaq 0x30(%rsp), %rdi
callq 0x17b4a
leaq 0xa8(%rsp), %rdi
callq 0x40b0
movl %ebx, %eax
addq $0x2b8, %rsp            # imm = 0x2B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x19a32(%rip), %rdi     # 0x2b8e8
leaq 0x19044(%rip), %rsi     # 0x2af01
leaq 0x19a31(%rip), %rcx     # 0x2b8f5
movl $0x61c, %edx            # imm = 0x61C
callq 0x4210
jmp 0x11ef8
movq %rax, %rbx
jmp 0x11f0f
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x5d02
jmp 0x11ee9
jmp 0x11ee6
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x4638
jmp 0x11efb
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x17b7e
leaq 0x30(%rsp), %rdi
callq 0x17b4a
leaq 0xa8(%rsp), %rdi
callq 0x40b0
movq %rbx, %rdi
callq 0x45a0