// File: schneebergerlab[P]GameteBinning/asPollinator_1.0.cpp
// Function: correct_haplotype2_with_consensus(std::map<int, POLLEN, std::less<int>, std::allocator<std::pair<int const, POLLEN>>>, std::map<int, POLLEN, std::less<int>, std::allocator<std::pair<int const, POLLEN>>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*)
bool correct_haplotype2_with_consensus(
                         map<int, POLLEN>                   maCluster,
                         map<int, POLLEN>                   paCluster,
                         string*                            matGT,
                         string*                            patGT)
{
    // this is stage 2 correction: using consensus of all pollen to determine maternal haplotype - used
    // from flip_pcluster function, patenral pollen seqs have been converted to maternal seqs
    map<int, POLLEN> bothCluster = maCluster;
    bothCluster.insert(paCluster.begin(), paCluster.end());
    int pollenNum                = bothCluster.size();    
    
    // position-wise consensus
    for(unsigned long ii = 0; ii < (*matGT).size(); ii ++)
    {
        map<string, int> baseCnt;             // parental allele cnt
        map<string, int>::iterator baseitr;
        //
        map<int, POLLEN>::iterator ppitr;     // traverse each collected pollen
        map<int, POLLEN>::iterator ppitr_end; // traverse each collected pollen   
        ppitr     = bothCluster.begin();
        ppitr_end = bothCluster.end();
        while(ppitr != ppitr_end)
        {
            POLLEN ptmp  = (*ppitr).second;
            string poSeq = ptmp.poSeq;   
            
            string base  = poSeq.substr(ii, 1);// can be ACGT/N
            
            baseitr = baseCnt.find(base);
            if(baseitr != baseCnt.end())
            {
                (*baseitr).second ++;
            }else
            {
                baseCnt.insert(std::pair<string, int>(base, 1));
            }
            ppitr ++;
        }
        // find major allele and minor allele
        baseitr = baseCnt.begin();
        map<string, int>::iterator baseitr_end = baseCnt.end();
        string majBase = "";
        int    majCnt  = 0;
        string minBase = "";
        int    minCnt  = 0;
        while(baseitr != baseitr_end)
        {
            string base = (*baseitr).first;
            int    cnt  = (*baseitr).second;
            if(base.compare("A")==0 ||
               base.compare("C")==0 || 
               base.compare("G")==0 ||
               base.compare("T")==0  )
            {
                if(cnt >  majCnt) // to consider 0 count
                {
                    majBase = base;
                    majCnt  = cnt;
                }else
                if(cnt >= minCnt) // to consider 0 count
                {
                    minBase = base;
                    minCnt  = cnt;
                }
                else ;              
            }
            baseitr ++;
        }
        //
        string matBase = (*matGT).substr(ii, 1);  // the base at current maternal haplotype, which should differ paternal one
        if(majBase.compare(minBase) != 0)               
        if(matBase.compare(majBase) != 0)         // swap as main base in maternal
        {
            if(majCnt > 0)
            {
                (*matGT).replace(ii, 1, majBase); //
                (*patGT).replace(ii, 1, matBase); //
            }
        }
        // if equal base then no change in the orignal pattern
    }
    cout << "   Check: 2nd corrected haplotypes: " << endl
         << "\t"  << *matGT                        << endl
         << "\t"  << *patGT                        << endl;     
    return true;
}

// Assembly:
subq $0x318, %rsp            # imm = 0x318
movq %rsi, %rax
movq %rdi, %rsi
movq %rax, 0x78(%rsp)
movq %rsi, 0x310(%rsp)
movq %rax, 0x308(%rsp)
movq %rdx, 0x300(%rsp)
movq %rcx, 0x2f8(%rsp)
leaq 0x2c8(%rsp), %rdi
movq %rdi, 0x80(%rsp)
callq 0x18fe0
movq 0x78(%rsp), %rdi
callq 0x19220
movq 0x78(%rsp), %rdi
movq %rax, 0x2c0(%rsp)
callq 0x19250
movq 0x80(%rsp), %rdi
movq %rax, 0x2b8(%rsp)
movq 0x2c0(%rsp), %rsi
movq 0x2b8(%rsp), %rdx
callq 0x1a000
jmp 0x1196a
leaq 0x2c8(%rsp), %rdi
callq 0x19740
movl %eax, 0x2a8(%rsp)
movq $0x0, 0x2a0(%rsp)
movq 0x2a0(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x300(%rsp), %rdi
callq 0x3250
movq %rax, %rcx
movq 0x70(%rsp), %rax
cmpq %rcx, %rax
jae 0x120cb
leaq 0x270(%rsp), %rdi
callq 0x1a040
leaq 0x268(%rsp), %rdi
callq 0x1a050
leaq 0x260(%rsp), %rdi
callq 0x19200
leaq 0x258(%rsp), %rdi
callq 0x19200
leaq 0x2c8(%rsp), %rdi
callq 0x19220
movq %rax, 0x250(%rsp)
movq 0x250(%rsp), %rax
movq %rax, 0x260(%rsp)
leaq 0x2c8(%rsp), %rdi
callq 0x19250
movq %rax, 0x248(%rsp)
movq 0x248(%rsp), %rax
movq %rax, 0x258(%rsp)
leaq 0x260(%rsp), %rdi
leaq 0x258(%rsp), %rsi
callq 0x19280
testb $0x1, %al
jne 0x11a51
jmp 0x11cb6
leaq 0x260(%rsp), %rdi
callq 0x192a0
movq %rax, %rsi
addq $0x8, %rsi
leaq 0x1d0(%rsp), %rdi
callq 0x192c0
jmp 0x11a74
leaq 0x1b0(%rsp), %rdi
leaq 0x1d0(%rsp), %rsi
callq 0x3160
jmp 0x11a8b
movq 0x2a0(%rsp), %rdx
leaq 0x190(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
movl $0x1, %ecx
callq 0x3350
jmp 0x11aaf
leaq 0x270(%rsp), %rdi
leaq 0x190(%rsp), %rsi
callq 0x1a070
movq %rax, 0x68(%rsp)
jmp 0x11acb
movq 0x68(%rsp), %rax
movq %rax, 0x188(%rsp)
movq 0x188(%rsp), %rax
movq %rax, 0x268(%rsp)
leaq 0x270(%rsp), %rdi
callq 0x1a0c0
movq %rax, 0x180(%rsp)
leaq 0x268(%rsp), %rdi
leaq 0x180(%rsp), %rsi
callq 0x1a0a0
testb $0x1, %al
jne 0x11b1b
jmp 0x11bb3
leaq 0x268(%rsp), %rdi
callq 0x1a0f0
movl 0x20(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x20(%rax)
jmp 0x11c47
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2b0(%rsp)
movl %eax, 0x2ac(%rsp)
jmp 0x121a1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2b0(%rsp)
movl %eax, 0x2ac(%rsp)
jmp 0x120b9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2b0(%rsp)
movl %eax, 0x2ac(%rsp)
jmp 0x11ca4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2b0(%rsp)
movl %eax, 0x2ac(%rsp)
jmp 0x11c97
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2b0(%rsp)
movl %eax, 0x2ac(%rsp)
jmp 0x11c8a
movl $0x1, 0x154(%rsp)
leaq 0x158(%rsp), %rdi
leaq 0x190(%rsp), %rsi
leaq 0x154(%rsp), %rdx
callq 0x1a160
jmp 0x11bdd
leaq 0x270(%rsp), %rdi
leaq 0x158(%rsp), %rsi
callq 0x1a110
movb %dl, 0x5f(%rsp)
movq %rax, 0x60(%rsp)
jmp 0x11bfd
movb 0x5f(%rsp), %al
movq 0x60(%rsp), %rcx
movq %rcx, 0x140(%rsp)
movb %al, 0x148(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x1a1a0
jmp 0x11c47
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2b0(%rsp)
movl %eax, 0x2ac(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x1a1a0
jmp 0x11c8a
leaq 0x260(%rsp), %rdi
xorl %esi, %esi
callq 0x193a0
movq %rax, 0x138(%rsp)
leaq 0x190(%rsp), %rdi
callq 0x31e0
leaq 0x1b0(%rsp), %rdi
callq 0x31e0
leaq 0x1d0(%rsp), %rdi
callq 0x18df0
jmp 0x11a33
leaq 0x190(%rsp), %rdi
callq 0x31e0
leaq 0x1b0(%rsp), %rdi
callq 0x31e0
leaq 0x1d0(%rsp), %rdi
callq 0x18df0
jmp 0x120b9
leaq 0x270(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x1a1b0
movq 0x48(%rsp), %rdi
movq %rax, 0x130(%rsp)
movq 0x130(%rsp), %rax
movq %rax, 0x268(%rsp)
callq 0x1a0c0
movq %rax, 0x128(%rsp)
leaq 0x107(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0x3570
movq 0x50(%rsp), %rdx
leaq 0x1a151(%rip), %rsi     # 0x2be61
leaq 0x108(%rsp), %rdi
callq 0x185e0
jmp 0x11d1f
leaq 0x107(%rsp), %rdi
callq 0x3390
movl $0x0, 0x100(%rsp)
leaq 0xdf(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x3570
movq 0x40(%rsp), %rdx
leaq 0x1a10c(%rip), %rsi     # 0x2be61
leaq 0xe0(%rsp), %rdi
callq 0x185e0
jmp 0x11d64
leaq 0xdf(%rsp), %rdi
callq 0x3390
movl $0x0, 0xd8(%rsp)
leaq 0x268(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x1a0a0
testb $0x1, %al
jne 0x11d9a
jmp 0x11f67
leaq 0x268(%rsp), %rdi
callq 0x1a0f0
movq %rax, %rsi
leaq 0xb8(%rsp), %rdi
callq 0x3160
jmp 0x11db9
leaq 0x268(%rsp), %rdi
callq 0x1a0f0
movl 0x20(%rax), %eax
movl %eax, 0xb4(%rsp)
leaq 0xb8(%rsp), %rdi
leaq 0x19efe(%rip), %rsi     # 0x2bcdd
callq 0x3100
cmpl $0x0, %eax
je 0x11e38
leaq 0xb8(%rsp), %rdi
leaq 0x19ee7(%rip), %rsi     # 0x2bcdf
callq 0x3100
cmpl $0x0, %eax
je 0x11e38
leaq 0xb8(%rsp), %rdi
leaq 0x19ed0(%rip), %rsi     # 0x2bce1
callq 0x3100
cmpl $0x0, %eax
je 0x11e38
leaq 0xb8(%rsp), %rdi
leaq 0x19eb9(%rip), %rsi     # 0x2bce3
callq 0x3100
cmpl $0x0, %eax
jne 0x11f3e
movl 0xb4(%rsp), %eax
cmpl 0x100(%rsp), %eax
jle 0x11f01
leaq 0x108(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0x3050
jmp 0x11e63
movl 0xb4(%rsp), %eax
movl %eax, 0x100(%rsp)
jmp 0x11f3c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2b0(%rsp)
movl %eax, 0x2ac(%rsp)
leaq 0x107(%rsp), %rdi
callq 0x3390
jmp 0x120b9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2b0(%rsp)
movl %eax, 0x2ac(%rsp)
leaq 0xdf(%rsp), %rdi
callq 0x3390
jmp 0x120ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2b0(%rsp)
movl %eax, 0x2ac(%rsp)
jmp 0x1209f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2b0(%rsp)
movl %eax, 0x2ac(%rsp)
leaq 0xb8(%rsp), %rdi
callq 0x31e0
jmp 0x1209f
movl 0xb4(%rsp), %eax
cmpl 0xd8(%rsp), %eax
jl 0x11f38
leaq 0xe0(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0x3050
jmp 0x11f28
movl 0xb4(%rsp), %eax
movl %eax, 0xd8(%rsp)
jmp 0x11f3a
jmp 0x11f3a
jmp 0x11f3c
jmp 0x11f3e
leaq 0x268(%rsp), %rdi
xorl %esi, %esi
callq 0x1a1e0
movq %rax, 0xa8(%rsp)
leaq 0xb8(%rsp), %rdi
callq 0x31e0
jmp 0x11d7c
movq 0x300(%rsp), %rsi
movq 0x2a0(%rsp), %rdx
leaq 0x88(%rsp), %rdi
movl $0x1, %ecx
callq 0x3350
jmp 0x11f8b
leaq 0x108(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x3040
movl %eax, 0x3c(%rsp)
jmp 0x11fa6
movl 0x3c(%rsp), %eax
cmpl $0x0, %eax
je 0x12052
leaq 0x88(%rsp), %rdi
leaq 0x108(%rsp), %rsi
callq 0x3040
movl %eax, 0x38(%rsp)
jmp 0x11fce
movl 0x38(%rsp), %eax
cmpl $0x0, %eax
je 0x12050
cmpl $0x0, 0x100(%rsp)
jle 0x1204e
movq 0x300(%rsp), %rdi
movq 0x2a0(%rsp), %rsi
movl $0x1, %edx
leaq 0x108(%rsp), %rcx
callq 0x3130
jmp 0x12005
movq 0x2f8(%rsp), %rdi
movq 0x2a0(%rsp), %rsi
movl $0x1, %edx
leaq 0x88(%rsp), %rcx
callq 0x3130
jmp 0x12029
jmp 0x1204e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2b0(%rsp)
movl %eax, 0x2ac(%rsp)
leaq 0x88(%rsp), %rdi
callq 0x31e0
jmp 0x1209f
jmp 0x12050
jmp 0x12052
leaq 0x88(%rsp), %rdi
callq 0x31e0
leaq 0xe0(%rsp), %rdi
callq 0x31e0
leaq 0x108(%rsp), %rdi
callq 0x31e0
leaq 0x270(%rsp), %rdi
callq 0x1a220
movq 0x2a0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x2a0(%rsp)
jmp 0x1198a
leaq 0xe0(%rsp), %rdi
callq 0x31e0
leaq 0x108(%rsp), %rdi
callq 0x31e0
leaq 0x270(%rsp), %rdi
callq 0x1a220
jmp 0x121a1
movq 0x26f06(%rip), %rdi     # 0x38fd8
leaq 0x19c0c(%rip), %rsi     # 0x2bce5
callq 0x3320
movq %rax, 0x30(%rsp)
jmp 0x120e5
movq 0x30(%rsp), %rdi
movq 0x26ed7(%rip), %rsi     # 0x38fc8
callq 0x3370
movq %rax, 0x28(%rsp)
jmp 0x120fd
movq 0x28(%rsp), %rdi
leaq 0x19d57(%rip), %rsi     # 0x2be60
callq 0x3320
movq %rax, 0x20(%rsp)
jmp 0x12115
movq 0x20(%rsp), %rdi
movq 0x300(%rsp), %rsi
callq 0x32e0
movq %rax, 0x18(%rsp)
jmp 0x1212e
movq 0x18(%rsp), %rdi
movq 0x26e8e(%rip), %rsi     # 0x38fc8
callq 0x3370
movq %rax, 0x10(%rsp)
jmp 0x12146
movq 0x10(%rsp), %rdi
leaq 0x19d0e(%rip), %rsi     # 0x2be60
callq 0x3320
movq %rax, 0x8(%rsp)
jmp 0x1215e
movq 0x8(%rsp), %rdi
movq 0x2f8(%rsp), %rsi
callq 0x32e0
movq %rax, (%rsp)
jmp 0x12176
movq (%rsp), %rdi
movq 0x26e47(%rip), %rsi     # 0x38fc8
callq 0x3370
jmp 0x12188
leaq 0x2c8(%rsp), %rdi
callq 0x18da0
movb $0x1, %al
andb $0x1, %al
addq $0x318, %rsp            # imm = 0x318
retq
leaq 0x2c8(%rsp), %rdi
callq 0x18da0
movq 0x2b0(%rsp), %rdi
callq 0x3560
nopl (%rax,%rax)