// File: 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:
subq $0x408, %rsp            # imm = 0x408
movq %rdi, 0x3f8(%rsp)
movl %esi, 0x3f4(%rsp)
movl %edx, 0x3f0(%rsp)
movq %rcx, 0x3e8(%rsp)
leaq 0x148(%rsp), %rdi
movq %rdi, 0x90(%rsp)
callq 0xf8b0
movq 0x90(%rsp), %rdi
movq 0x3f8(%rsp), %rsi
movl $0x8, %edx
callq 0xf9c0
jmp 0x2b976
movq 0x148(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x148(%rsp,%rax), %rdi
callq 0x5760
movb %al, 0x8f(%rsp)
jmp 0x2b998
movb 0x8f(%rsp), %al
testb $0x1, %al
jne 0x2ba22
jmp 0x2b9a5
movq 0x5961c(%rip), %rdi     # 0x84fc8
leaq 0x3cec8(%rip), %rsi     # 0x6887b
callq 0x5460
movq %rax, 0x80(%rsp)
jmp 0x2b9c2
movq 0x80(%rsp), %rdi
movq 0x3f8(%rsp), %rsi
callq 0x5460
movq %rax, 0x78(%rsp)
jmp 0x2b9de
movq 0x78(%rsp), %rdi
movq 0x595c6(%rip), %rsi     # 0x84fb0
callq 0x54b0
jmp 0x2b9f1
movb $0x0, 0x407(%rsp)
movl $0x1, 0x138(%rsp)
jmp 0x2be97
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x140(%rsp)
movl %eax, 0x13c(%rsp)
jmp 0x2beb5
movq 0x5959f(%rip), %rdi     # 0x84fc8
leaq 0x3ce7b(%rip), %rsi     # 0x688ab
callq 0x5460
movq %rax, 0x70(%rsp)
jmp 0x2ba3c
movq 0x70(%rsp), %rdi
movq 0x59568(%rip), %rsi     # 0x84fb0
callq 0x54b0
jmp 0x2ba4f
jmp 0x2ba51
movq $0x0, 0x130(%rsp)
movq 0x148(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x148(%rsp,%rax), %rdi
callq 0x5760
movb %al, 0x6f(%rsp)
jmp 0x2ba7c
movb 0x6f(%rsp), %al
testb $0x1, %al
jne 0x2ba89
jmp 0x2bdd1
leaq 0x10f(%rsp), %rdi
movq %rdi, 0x60(%rsp)
callq 0x57c0
movq 0x60(%rsp), %rdx
leaq 0x3f0ed(%rip), %rsi     # 0x6ab94
leaq 0x110(%rsp), %rdi
callq 0x6880
jmp 0x2bab6
leaq 0x10f(%rsp), %rdi
callq 0x54d0
leaq 0x2d0(%rsp), %rdi
leaq 0x110(%rsp), %rsi
callq 0x50c0
jmp 0x2bada
leaq 0x110(%rsp), %rdi
callq 0x5310
cmpq $0x0, %rax
je 0x2bb12
xorl %eax, %eax
movl %eax, %esi
leaq 0x110(%rsp), %rdi
callq 0x5880
movq %rax, 0x58(%rsp)
jmp 0x2bb05
movq 0x58(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x23, %eax
jne 0x2bb61
movl $0x2, 0x138(%rsp)
jmp 0x2bd8e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x140(%rsp)
movl %eax, 0x13c(%rsp)
leaq 0x10f(%rsp), %rdi
callq 0x54d0
jmp 0x2beb5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x140(%rsp)
movl %eax, 0x13c(%rsp)
jmp 0x2bdbf
movb $0x9, 0xef(%rsp)
leaq 0xf0(%rsp), %rdi
leaq 0x110(%rsp), %rsi
leaq 0xef(%rsp), %rdx
callq 0x60790
jmp 0x2bb88
leaq 0x110(%rsp), %rdi
callq 0x5310
cmpq $0x7, %rax
jae 0x2bbab
movl $0x2, 0x138(%rsp)
jmp 0x2bd81
leaq 0xf0(%rsp), %rdi
movl $0x5, %esi
callq 0x88f0
movq %rax, %rdi
callq 0x51d0
movq %rax, %rdi
callq 0x56a0
movl %eax, 0xe8(%rsp)
leaq 0xf0(%rsp), %rdi
movl $0x3, %esi
callq 0x88f0
movq %rax, %rdi
callq 0x51d0
movq %rax, %rdi
callq 0x56a0
movl %eax, 0xe4(%rsp)
movl 0xe8(%rsp), %eax
cmpl 0x3f4(%rsp), %eax
jg 0x2bc43
movl 0xe4(%rsp), %eax
cmpl 0x3f0(%rsp), %eax
jg 0x2bc43
movl 0xe8(%rsp), %eax
imull 0x3f0(%rsp), %eax
movl 0x3f4(%rsp), %ecx
imull 0xe4(%rsp), %ecx
cmpl %ecx, %eax
jle 0x2bd76
leaq 0xd0(%rsp), %rdi
callq 0x2dfc0
jmp 0x2bc52
leaq 0xf0(%rsp), %rdi
movq %rdi, 0x40(%rsp)
movl $0x1, %esi
callq 0x88f0
movq %rax, %rdi
callq 0x51d0
movq %rax, %rdi
xorl %edx, %edx
movl %edx, 0x3c(%rsp)
movl %edx, %esi
movq %rsi, 0x48(%rsp)
callq 0x5160
movq 0x40(%rsp), %rdi
movq %rax, 0xd0(%rsp)
movl $0x2, %esi
callq 0x88f0
movq %rax, %rdi
callq 0x51d0
movl 0x3c(%rsp), %edx
movq 0x48(%rsp), %rsi
movq %rax, %rdi
callq 0x5160
movq 0x40(%rsp), %rdi
movq 0x48(%rsp), %rsi
movq %rax, 0xd8(%rsp)
movq 0x3e8(%rsp), %rax
movq %rax, 0x50(%rsp)
callq 0x88f0
movq %rax, %rsi
leaq 0xa0(%rsp), %rdi
leaq 0xd0(%rsp), %rdx
callq 0x2e010
jmp 0x2bcf4
movq 0x50(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x2dfe0
movq %rax, 0x30(%rsp)
jmp 0x2bd0d
movq 0x30(%rsp), %rax
movq %rax, 0x98(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0x2e060
movq 0x130(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x130(%rsp)
jmp 0x2bd76
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x140(%rsp)
movl %eax, 0x13c(%rsp)
jmp 0x2bdb2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x140(%rsp)
movl %eax, 0x13c(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0x2e060
jmp 0x2bdb2
movl $0x0, 0x138(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0x8910
leaq 0x110(%rsp), %rdi
callq 0x58b8
movl 0x138(%rsp), %eax
testl %eax, %eax
je 0x2bdad
jmp 0x2bda8
jmp 0x2ba5d
jmp 0x2ba5d
leaq 0xf0(%rsp), %rdi
callq 0x8910
leaq 0x110(%rsp), %rdi
callq 0x58b8
jmp 0x2beb5
leaq 0x148(%rsp), %rdi
callq 0x65264
jmp 0x2bde0
movq 0x591e1(%rip), %rdi     # 0x84fc8
leaq 0x3cb05(%rip), %rsi     # 0x688f3
callq 0x5460
movq %rax, 0x28(%rsp)
jmp 0x2bdfa
movq 0x28(%rsp), %rdi
movl 0x3f4(%rsp), %esi
callq 0x5790
movq %rax, 0x20(%rsp)
jmp 0x2be12
movq 0x20(%rsp), %rdi
leaq 0x3cb15(%rip), %rsi     # 0x68933
callq 0x5460
movq %rax, 0x18(%rsp)
jmp 0x2be2a
movq 0x18(%rsp), %rdi
movl 0x3f0(%rsp), %esi
callq 0x5790
movq %rax, 0x10(%rsp)
jmp 0x2be42
movq 0x10(%rsp), %rdi
leaq 0x3c3ee(%rip), %rsi     # 0x6823c
callq 0x5460
movq %rax, 0x8(%rsp)
jmp 0x2be5a
movq 0x8(%rsp), %rdi
movq 0x130(%rsp), %rsi
callq 0x50f0
movq %rax, (%rsp)
jmp 0x2be72
movq (%rsp), %rdi
movq 0x59133(%rip), %rsi     # 0x84fb0
callq 0x54b0
jmp 0x2be84
movb $0x1, 0x407(%rsp)
movl $0x1, 0x138(%rsp)
leaq 0x148(%rsp), %rdi
callq 0xfe60
movb 0x407(%rsp), %al
andb $0x1, %al
addq $0x408, %rsp            # imm = 0x408
retq
leaq 0x148(%rsp), %rdi
callq 0xfe60
movq 0x140(%rsp), %rdi
callq 0x57b0
nop