// File: 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:
subq $0x3d8, %rsp            # imm = 0x3D8
movq %rdx, 0xd8(%rsp)
movq %rdi, 0x3c8(%rsp)
movsd %xmm0, 0x3c0(%rsp)
movq %rsi, 0x3b8(%rsp)
movq %rdx, 0x3b0(%rsp)
movq 0x5f931(%rip), %rdi     # 0x84fc8
leaq 0x432ac(%rip), %rsi     # 0x6894a
callq 0x5460
movq 0xd8(%rsp), %rsi
movq %rax, %rdi
callq 0x53e0
movq %rax, %rdi
leaq 0x432a0(%rip), %rsi     # 0x6895d
callq 0x5460
movq %rax, %rdi
movq 0x5f8e4(%rip), %rsi     # 0x84fb0
callq 0x54b0
leaq 0x1a0(%rsp), %rdi
movq %rdi, 0xe0(%rsp)
callq 0x5530
movq 0xe0(%rsp), %rdi
movq 0x3c8(%rsp), %rsi
movl $0x8, %edx
callq 0x53f0
jmp 0x25702
movq 0x1a0(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x1a0(%rsp,%rax), %rdi
callq 0x5760
movb %al, 0xd7(%rsp)
jmp 0x25724
movb 0xd7(%rsp), %al
testb $0x1, %al
jne 0x257b8
jmp 0x25735
movq 0x5f88c(%rip), %rdi     # 0x84fc8
leaq 0x4322d(%rip), %rsi     # 0x68970
callq 0x5460
movq %rax, 0xc8(%rsp)
jmp 0x25752
movq 0xc8(%rsp), %rdi
movq 0x3c8(%rsp), %rsi
callq 0x5460
movq %rax, 0xc0(%rsp)
jmp 0x25771
movq 0xc0(%rsp), %rdi
movq 0x5f830(%rip), %rsi     # 0x84fb0
callq 0x54b0
jmp 0x25787
movb $0x0, 0x3d7(%rsp)
movl $0x1, 0x190(%rsp)
jmp 0x25ff2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x198(%rsp)
movl %eax, 0x194(%rsp)
jmp 0x26010
leaq 0x178(%rsp), %rdi
callq 0x2e070
leaq 0x160(%rsp), %rdi
callq 0x2e080
movl $0x0, 0x15c(%rsp)
movq $0x0, 0x150(%rsp)
movl $0x0, 0x14c(%rsp)
movl $0x0, 0x148(%rsp)
movb $0x9, 0x147(%rsp)
movq 0x1a0(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x1a0(%rsp,%rax), %rdi
callq 0x5760
movb %al, 0xbf(%rsp)
jmp 0x25829
movb 0xbf(%rsp), %al
testb $0x1, %al
jne 0x25839
jmp 0x25b1b
leaq 0x11f(%rsp), %rdi
movq %rdi, 0xb0(%rsp)
callq 0x57c0
movq 0xb0(%rsp), %rdx
leaq 0x45337(%rip), %rsi     # 0x6ab94
leaq 0x120(%rsp), %rdi
callq 0x6880
jmp 0x2586c
leaq 0x11f(%rsp), %rdi
callq 0x54d0
leaq 0x1a0(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x50c0
jmp 0x25890
leaq 0x120(%rsp), %rdi
callq 0x5310
cmpq $0x0, %rax
je 0x258ce
xorl %eax, %eax
movl %eax, %esi
leaq 0x120(%rsp), %rdi
callq 0x5880
movq %rax, 0xa8(%rsp)
jmp 0x258be
movq 0xa8(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x23, %eax
jne 0x25936
movl $0x2, 0x190(%rsp)
jmp 0x25ae5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x198(%rsp)
movl %eax, 0x194(%rsp)
jmp 0x25fd6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x198(%rsp)
movl %eax, 0x194(%rsp)
leaq 0x11f(%rsp), %rdi
callq 0x54d0
jmp 0x25fd6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x198(%rsp)
movl %eax, 0x194(%rsp)
jmp 0x25b09
movsbl 0x147(%rsp), %eax
cmpl $0x9, %eax
jne 0x25969
leaq 0x120(%rsp), %rdi
leaq 0x45241(%rip), %rsi     # 0x6ab93
xorl %eax, %eax
movl %eax, %edx
callq 0x5870
cmpq $-0x1, %rax
jne 0x25969
movb $0x20, 0x147(%rsp)
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
leaq 0x147(%rsp), %rdx
callq 0x60790
jmp 0x25988
leaq 0x120(%rsp), %rdi
callq 0x5310
cmpq $0x2, %rax
jae 0x259ab
movl $0x2, 0x190(%rsp)
jmp 0x25ad8
xorl %eax, %eax
movl %eax, 0xa4(%rsp)
movl %eax, %esi
movq %rsi, 0x98(%rsp)
leaq 0x100(%rsp), %rdi
movq %rdi, 0x90(%rsp)
callq 0x88f0
movq %rax, %rdi
callq 0x51d0
movq %rax, %rdi
callq 0x5570
callq 0x51e0
movq 0x90(%rsp), %rdi
cvttsd2si %xmm0, %eax
movl %eax, 0xfc(%rsp)
movl $0x1, %esi
callq 0x88f0
movq %rax, %rdi
callq 0x51d0
movq 0x98(%rsp), %rsi
movl 0xa4(%rsp), %edx
movq %rax, %rdi
callq 0x5160
movq %rax, 0xf0(%rsp)
movl 0x14c(%rsp), %eax
incl %eax
movl %eax, 0x14c(%rsp)
leaq 0x178(%rsp), %rdi
leaq 0xfc(%rsp), %rsi
callq 0x2e090
jmp 0x25a53
leaq 0x160(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x2e100
jmp 0x25a6a
movq 0xf0(%rsp), %rax
cmpq 0x150(%rsp), %rax
jbe 0x25acd
movq 0xf0(%rsp), %rax
movq %rax, 0x150(%rsp)
movl 0xfc(%rsp), %eax
movl %eax, 0x15c(%rsp)
movl 0x14c(%rsp), %eax
movl %eax, 0x148(%rsp)
jmp 0x25acd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x198(%rsp)
movl %eax, 0x194(%rsp)
leaq 0x100(%rsp), %rdi
callq 0x8910
jmp 0x25b09
movl $0x0, 0x190(%rsp)
leaq 0x100(%rsp), %rdi
callq 0x8910
leaq 0x120(%rsp), %rdi
callq 0x58b8
movl 0x190(%rsp), %eax
testl %eax, %eax
je 0x25b04
jmp 0x25aff
jmp 0x25807
jmp 0x25807
leaq 0x120(%rsp), %rdi
callq 0x58b8
jmp 0x25fd6
cmpl $0x1, 0x148(%rsp)
jl 0x25b27
jmp 0x25b46
leaq 0x42e71(%rip), %rdi     # 0x6899f
leaq 0x42408(%rip), %rsi     # 0x67f3d
movl $0x61c, %edx            # imm = 0x61C
leaq 0x42e6b(%rip), %rcx     # 0x689ac
callq 0x52d0
movl 0x148(%rsp), %eax
movl %eax, 0xec(%rsp)
movslq 0xec(%rsp), %rax
movq %rax, 0x88(%rsp)
leaq 0x178(%rsp), %rdi
callq 0x2e170
movq %rax, %rcx
movq 0x88(%rsp), %rax
cmpq %rcx, %rax
jae 0x25de4
movslq 0xec(%rsp), %rsi
leaq 0x160(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0x2e190
movq 0x58(%rsp), %rdi
movq (%rax), %xmm0
movaps 0x41521(%rip), %xmm1    # 0x670d0
movaps %xmm1, 0x60(%rsp)
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x41520(%rip), %xmm1    # 0x670e0
movaps %xmm1, 0x70(%rsp)
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movsd %xmm0, 0x80(%rsp)
movl 0x148(%rsp), %eax
decl %eax
movslq %eax, %rsi
callq 0x2e190
movaps 0x60(%rsp), %xmm3
movaps 0x70(%rsp), %xmm2
movsd 0x80(%rsp), %xmm1
movq (%rax), %xmm0
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
subpd %xmm2, %xmm0
movaps %xmm0, %xmm2
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm2, %xmm0
movsd 0x41490(%rip), %xmm2    # 0x670b0
mulsd %xmm2, %xmm0
divsd %xmm0, %xmm1
movsd 0x3c0(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x25c95
movl 0xec(%rsp), %eax
cmpl 0x148(%rsp), %eax
jne 0x25c6a
movslq 0xec(%rsp), %rsi
leaq 0x178(%rsp), %rdi
callq 0x2e1b0
movl (%rax), %ecx
movq 0x3b8(%rsp), %rax
movl %ecx, (%rax)
jmp 0x25c90
movl 0xec(%rsp), %eax
subl $0x1, %eax
movslq %eax, %rsi
leaq 0x178(%rsp), %rdi
callq 0x2e1b0
movl (%rax), %ecx
movq 0x3b8(%rsp), %rax
movl %ecx, (%rax)
jmp 0x25de4
movq 0xd8(%rsp), %rdi
leaq 0x41e1e(%rip), %rsi     # 0x67ac2
callq 0x5140
cmpl $0x0, %eax
jne 0x25d32
movslq 0xec(%rsp), %rsi
leaq 0x178(%rsp), %rdi
callq 0x2e1b0
cvtsi2sdl (%rax), %xmm0
movsd %xmm0, 0x50(%rsp)
movl 0x148(%rsp), %eax
subl $0x1, %eax
movslq %eax, %rsi
leaq 0x178(%rsp), %rdi
callq 0x2e1b0
movsd 0x50(%rsp), %xmm0
cvtsi2sdl (%rax), %xmm2
movsd 0x413c3(%rip), %xmm1    # 0x670c0
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x25d32
movl 0xec(%rsp), %eax
subl $0x1, %eax
movslq %eax, %rsi
leaq 0x178(%rsp), %rdi
callq 0x2e1b0
movl (%rax), %ecx
movq 0x3b8(%rsp), %rax
movl %ecx, (%rax)
jmp 0x25de4
movq 0xd8(%rsp), %rdi
leaq 0x41dab(%rip), %rsi     # 0x67aec
callq 0x5140
cmpl $0x0, %eax
jne 0x25dc8
movslq 0xec(%rsp), %rsi
leaq 0x178(%rsp), %rdi
callq 0x2e1b0
cvtsi2sdl (%rax), %xmm0
movsd %xmm0, 0x48(%rsp)
movl 0x148(%rsp), %eax
subl $0x1, %eax
movslq %eax, %rsi
leaq 0x178(%rsp), %rdi
callq 0x2e1b0
movsd 0x48(%rsp), %xmm0
cvtsi2sdl (%rax), %xmm2
movsd 0x4132a(%rip), %xmm1    # 0x670c0
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x25dc8
movl 0xec(%rsp), %eax
subl $0x1, %eax
movslq %eax, %rsi
leaq 0x178(%rsp), %rdi
callq 0x2e1b0
movl (%rax), %ecx
movq 0x3b8(%rsp), %rax
movl %ecx, (%rax)
jmp 0x25de4
jmp 0x25dca
jmp 0x25dcc
jmp 0x25dce
movl 0xec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xec(%rsp)
jmp 0x25b54
movq 0xd8(%rsp), %rdi
leaq 0x41ccf(%rip), %rsi     # 0x67ac2
callq 0x5140
cmpl $0x0, %eax
jne 0x25ea1
movq 0x3b8(%rsp), %rax
movl (%rax), %ecx
decl %ecx
movl %ecx, (%rax)
movq 0x5f1b2(%rip), %rdi     # 0x84fc8
leaq 0x42bd3(%rip), %rsi     # 0x689f0
callq 0x5460
movq %rax, 0x40(%rsp)
jmp 0x25e29
movq 0x40(%rsp), %rdi
movq 0x3b8(%rsp), %rax
movl (%rax), %esi
callq 0x5790
movq %rax, 0x38(%rsp)
jmp 0x25e44
movq 0x38(%rsp), %rdi
leaq 0x42621(%rip), %rsi     # 0x68471
callq 0x5460
movq %rax, 0x30(%rsp)
jmp 0x25e5c
movq 0x30(%rsp), %rdi
movq 0x5f148(%rip), %rsi     # 0x84fb0
callq 0x54b0
jmp 0x25e6f
movq 0x5f152(%rip), %rdi     # 0x84fc8
leaq 0x42bb2(%rip), %rsi     # 0x68a2f
callq 0x5460
movq %rax, 0x28(%rsp)
jmp 0x25e89
movq 0x28(%rsp), %rdi
movq 0x5f11b(%rip), %rsi     # 0x84fb0
callq 0x54b0
jmp 0x25e9c
jmp 0x25fa7
movq 0xd8(%rsp), %rdi
leaq 0x41c3c(%rip), %rsi     # 0x67aec
callq 0x5140
cmpl $0x0, %eax
jne 0x25f65
movq 0x3b8(%rsp), %rax
movl (%rax), %ecx
imull $0x3e8, %ecx, %ecx      # imm = 0x3E8
addl $0x3e8, %ecx            # imm = 0x3E8
movl %ecx, (%rax)
movq 0x5f0eb(%rip), %rdi     # 0x84fc8
leaq 0x42b7d(%rip), %rsi     # 0x68a61
callq 0x5460
movq %rax, 0x20(%rsp)
jmp 0x25ef0
movq 0x20(%rsp), %rdi
movq 0x3b8(%rsp), %rax
movl (%rax), %esi
callq 0x5790
movq %rax, 0x18(%rsp)
jmp 0x25f0b
movq 0x18(%rsp), %rdi
leaq 0x42557(%rip), %rsi     # 0x6846e
callq 0x5460
movq %rax, 0x10(%rsp)
jmp 0x25f23
movq 0x10(%rsp), %rdi
movq 0x5f081(%rip), %rsi     # 0x84fb0
callq 0x54b0
jmp 0x25f36
movq 0x5f08b(%rip), %rdi     # 0x84fc8
leaq 0x42b53(%rip), %rsi     # 0x68a97
callq 0x5460
movq %rax, 0x8(%rsp)
jmp 0x25f50
movq 0x8(%rsp), %rdi
movq 0x5f054(%rip), %rsi     # 0x84fb0
callq 0x54b0
jmp 0x25f63
jmp 0x25fa5
movq 0x5f05c(%rip), %rdi     # 0x84fc8
leaq 0x42b5a(%rip), %rsi     # 0x68acd
callq 0x5460
movq %rax, (%rsp)
jmp 0x25f7e
movq (%rsp), %rdi
movq 0x5f027(%rip), %rsi     # 0x84fb0
callq 0x54b0
jmp 0x25f90
movb $0x0, 0x3d7(%rsp)
movl $0x1, 0x190(%rsp)
jmp 0x25fba
jmp 0x25fa7
movb $0x1, 0x3d7(%rsp)
movl $0x1, 0x190(%rsp)
leaq 0x160(%rsp), %rdi
callq 0x2e1d0
leaq 0x178(%rsp), %rdi
callq 0x2e230
jmp 0x25ff2
leaq 0x160(%rsp), %rdi
callq 0x2e1d0
leaq 0x178(%rsp), %rdi
callq 0x2e230
jmp 0x26010
leaq 0x1a0(%rsp), %rdi
callq 0x50e0
movb 0x3d7(%rsp), %al
andb $0x1, %al
addq $0x3d8, %rsp            # imm = 0x3D8
retq
leaq 0x1a0(%rsp), %rdi
callq 0x50e0
movq 0x198(%rsp), %rdi
callq 0x57b0
nopw (%rax,%rax)