// File: /workspace/github_cpp_makefile_star2_O2/schneebergerlab[P]DrLink/detect_recombsite.cpp
// Function: get_bad_molecule(char const*, int, int, std::multimap<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<unsigned long, unsigned long>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, std::pair<unsigned long, unsigned long>>>>*)
bool get_bad_molecule(const char* file, 
                      int         maxReadNum,
                      int         maxMoleLen,
                      multimap<string, std::pair<unsigned long, unsigned long> >* badMolecule)
{
    // 1. if molecule length > cutoff,      collect it as bad
    // 2. if molecule read number > cutoff, collect it as bad
    // 3. if rNumber > mLen/mLen_cutoff * rNumber_cutoff, collect it as bad - 2018-07-30
    // molecule table: statistics of all moleclues: generated by 'DrLink molecule'
    // format: chr#barcode    first_aligned   last_aligned    molecule_len    molecule_cov    read_num    Uni_flag
    igzstream fp;
    fp.open(file);
    if(!fp.good())
    {
        cout << "   Error: cannot open read number distribution " << file << endl;
        return false;
    }
    else
    {
        cout << "   Info: collecting bad molecules (with larger read number or size)... " << endl;
    }
    unsigned long numibad = 0;
    while(fp.good())
    {
        string line("");
        getline(fp, line);
        if(line.size()==0 || line[0]=='#') continue;
        
        vector<string> lineinfo = split_string(line, '\t');
        if(line.size() < 7) continue;
        
        int readnum = atoi(lineinfo[5].c_str());
        int molelen = atoi(lineinfo[3].c_str()); 
        if( (readnum>maxReadNum || molelen>maxMoleLen) ||  
            (readnum*maxMoleLen > maxReadNum*molelen)
          )// potential overlapping molecules
        {
            std::pair <unsigned long, unsigned long> span;
            span.first  = strtoul(lineinfo[1].c_str(), NULL, 0);
            span.second = strtoul(lineinfo[2].c_str(), NULL, 0);
            // chr+"#"+barcode => (sta, end) : allow multi-aligns with the same barcode.
            (*badMolecule).insert(std::pair<string, std::pair<unsigned long, unsigned long> >(lineinfo[0], span));  
            numibad ++;          
        }
    }
    fp.close();
    cout << "   Info: number of collected bad molecules with read number >  " << maxReadNum 
         << " or molecule length > "                                          << maxMoleLen << " bp: "
         << numibad << endl;    
    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x328, %rsp            # imm = 0x328
movq %rcx, 0x18(%rsp)
movl %edx, 0x4(%rsp)
movl %esi, 0x8(%rsp)
movq %rdi, %rbx
leaq 0x88(%rsp), %r14
movq %r14, %rdi
callq 0x94d2
pushq $0x8
popq %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x27e38
movq 0x88(%rsp), %rax
movq -0x18(%rax), %rax
movl 0xa8(%rsp,%rax), %eax
movl %eax, 0xc(%rsp)
testl %eax, %eax
je 0x14c24
movq 0x283c8(%rip), %rdi     # 0x3cfc8
leaq 0x16bbd(%rip), %rsi     # 0x2b7c4
callq 0x4330
movq %rax, %rdi
movq %rbx, %rsi
callq 0x4330
movq %rax, %rdi
callq 0x41c0
jmp 0x14dfa
movq 0x2839d(%rip), %rdi     # 0x3cfc8
leaq 0x16bc2(%rip), %rsi     # 0x2b7f4
callq 0x4330
movq %rax, %rdi
callq 0x41c0
leaq 0x210(%rsp), %r12
movq $0x0, 0x10(%rsp)
leaq 0x18ec3(%rip), %r13     # 0x2db1a
leaq 0x38(%rsp), %r15
leaq 0x58(%rsp), %r14
leaq 0x20(%rsp), %rbx
movq 0x88(%rsp), %rax
movq -0x18(%rax), %rax
cmpl $0x0, 0xa8(%rsp,%rax)
jne 0x14d8f
movq %r15, %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x4d3e
movq %r12, %rdi
movq %r15, %rsi
callq 0x4090
cmpq $0x0, 0x40(%rsp)
je 0x14d82
movq 0x38(%rsp), %rax
cmpb $0x23, (%rax)
je 0x14d82
movb $0x9, 0x58(%rsp)
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x26120
cmpq $0x7, 0x40(%rsp)
jb 0x14d7a
movq %r12, %r13
movq %rbx, %r12
movq 0x20(%rsp), %rbx
movq 0xa0(%rbx), %rdi
callq 0x44c0
movl %eax, %ebp
movq 0x60(%rbx), %rdi
callq 0x44c0
cmpl 0x8(%rsp), %ebp
setg %cl
cmpl 0x4(%rsp), %eax
setg %dl
orb %cl, %dl
jne 0x14d14
imull 0x4(%rsp), %ebp
imull 0x8(%rsp), %eax
cmpl %eax, %ebp
jle 0x14d6d
movq 0x20(%rbx), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x4130
movq %rax, %rbp
movq 0x20(%rsp), %rax
movq 0x40(%rax), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x4130
movq %rax, %rbx
movq 0x20(%rsp), %rsi
movq %r14, %rdi
callq 0x4400
movq %rbp, 0x78(%rsp)
movq %rbx, 0x80(%rsp)
movq 0x18(%rsp), %rdi
movq %r14, %rsi
callq 0x179c4
movq %r14, %rdi
callq 0x4638
incq 0x10(%rsp)
movq %r12, %rbx
movq %r13, %r12
leaq 0x18da0(%rip), %r13     # 0x2db1a
movq %rbx, %rdi
callq 0x5d02
movq %r15, %rdi
callq 0x4638
jmp 0x14c66
leaq 0x88(%rsp), %rdi
callq 0x280e0
movq 0x28225(%rip), %rdi     # 0x3cfc8
leaq 0x16a92(%rip), %rsi     # 0x2b83c
callq 0x4330
movq %rax, %rdi
movl 0x8(%rsp), %esi
callq 0x4580
leaq 0x16aba(%rip), %rsi     # 0x2b87c
movq %rax, %rdi
callq 0x4330
movq %rax, %rdi
movl 0x4(%rsp), %esi
callq 0x4580
leaq 0x163d8(%rip), %rsi     # 0x2b1b5
movq %rax, %rdi
callq 0x4330
movq %rax, %rdi
movq 0x10(%rsp), %rsi
callq 0x4230
movq %rax, %rdi
callq 0x41c0
cmpl $0x0, 0xc(%rsp)
sete %bl
leaq 0x88(%rsp), %rdi
callq 0x96aa
movl %ebx, %eax
addq $0x328, %rsp            # imm = 0x328
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
callq 0x4638
jmp 0x14e35
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x5d02
jmp 0x14e4a
jmp 0x14e56
jmp 0x14e56
jmp 0x14e47
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x4638
jmp 0x14e59
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x96aa
movq %rbx, %rdi
callq 0x45a0