// File: /workspace/github_cpp_makefile_star2_O1/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x158, %rsp            # imm = 0x158
movq %rcx, 0x58(%rsp)
movq %rdx, %r15
movq %rsi, %rbx
movq %rdi, %rsi
leaq 0x128(%rsp), %r14
movq %r14, %rdi
callq 0x152b4
movq 0x18(%rbx), %rsi
addq $0x8, %rbx
movq %r14, %rdi
movq %rbx, %rdx
callq 0x17a9c
cmpq $0x0, 0x8(%r15)
je 0xfa0f
leaq 0x130(%rsp), %r14
leaq 0x18(%rsp), %rbx
leaq 0x8(%rsp), %rbp
movq $0x0, (%rsp)
movq %r15, 0x50(%rsp)
movl $0x0, 0x68(%rsp)
xorl %ecx, %ecx
movq %rcx, 0x70(%rsp)
leaq 0x68(%rsp), %rax
movq %rax, 0x78(%rsp)
movq %rax, 0x80(%rsp)
movq %rcx, 0x88(%rsp)
movq 0x140(%rsp), %r13
cmpq %r14, %r13
je 0xf78f
leaq 0x28(%r13), %rsi
leaq 0xb0(%rsp), %rdi
callq 0x148ea
movq %rbx, 0x8(%rsp)
movq 0xb0(%rsp), %rsi
movq 0xb8(%rsp), %rdx
addq %rsi, %rdx
movq %rbp, %rdi
callq 0x16592
movl $0x1, %ecx
leaq 0x90(%rsp), %r12
movq %r12, %rdi
movq %rbp, %rsi
movq (%rsp), %rdx
callq 0x32b0
leaq 0x60(%rsp), %rdi
movq %r12, %rsi
callq 0x17bf4
leaq 0x68(%rsp), %rcx
cmpq %rcx, %rax
je 0xf658
incl 0x40(%rax)
jmp 0xf6b3
leaq 0x38(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x90(%rsp), %rsi
movq 0x98(%rsp), %rdx
addq %rsi, %rdx
leaq 0x28(%rsp), %r12
movq %r12, %rdi
callq 0x16592
movl $0x1, 0x48(%rsp)
leaq 0x60(%rsp), %rdi
movq %r12, %rsi
callq 0x17c7e
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0xf6b3
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3290
movq %r13, %rdi
callq 0x31c0
movq %rax, %r13
movq 0x90(%rsp), %rdi
leaq 0xa0(%rsp), %rax
cmpq %rax, %rdi
je 0xf6e3
movq 0xa0(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0x8(%rsp), %rdi
cmpq %rbx, %rdi
je 0xf6fa
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0x110(%rsp), %rdi
testq %rdi, %rdi
je 0xf717
movq 0x120(%rsp), %rsi
subq %rdi, %rsi
callq 0x3290
movq 0xf0(%rsp), %rdi
leaq 0x100(%rsp), %rax
cmpq %rax, %rdi
je 0xf73c
movq 0x100(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0xd0(%rsp), %rdi
leaq 0xe0(%rsp), %rax
cmpq %rax, %rdi
je 0xf761
movq 0xe0(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0xb0(%rsp), %rdi
leaq 0xc0(%rsp), %rax
cmpq %rax, %rdi
je 0xf5e6
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x3290
jmp 0xf5e6
movq 0x78(%rsp), %r13
leaq 0xc0(%rsp), %rax
movq %rax, 0xb0(%rsp)
leaq 0xb0(%rsp), %rdi
leaq 0xa716(%rip), %r14      # 0x19ec9
movq %r14, %rsi
movq %r14, %rdx
callq 0x16622
leaq 0x38(%rsp), %rax
movq %rax, 0x28(%rsp)
leaq 0x28(%rsp), %rdi
movq %r14, %rsi
movq %r14, %rdx
callq 0x16622
xorl %r14d, %r14d
leaq 0x68(%rsp), %rax
cmpq %rax, %r13
je 0xf8ba
xorl %r15d, %r15d
movq %rbx, 0x8(%rsp)
movq 0x20(%r13), %rsi
movq 0x28(%r13), %rdx
addq %rsi, %rdx
movq %rbp, %rdi
callq 0x16592
movl 0x40(%r13), %r12d
movq %rbp, %rdi
leaq 0xa533(%rip), %rsi      # 0x19d45
callq 0x30b0
testl %eax, %eax
je 0xf854
movq %rbp, %rdi
leaq 0xa522(%rip), %rsi      # 0x19d47
callq 0x30b0
testl %eax, %eax
je 0xf854
movq %rbp, %rdi
leaq 0xa511(%rip), %rsi      # 0x19d49
callq 0x30b0
testl %eax, %eax
je 0xf854
movq %rbp, %rdi
leaq 0xa500(%rip), %rsi      # 0x19d4b
callq 0x30b0
testl %eax, %eax
jne 0xf883
cmpl %r15d, %r12d
jle 0xf86e
leaq 0xb0(%rsp), %rdi
movq %rbp, %rsi
callq 0x3160
movl %r12d, %r15d
jmp 0xf883
cmpl %r14d, %r12d
jl 0xf883
leaq 0x28(%rsp), %rdi
movq %rbp, %rsi
callq 0x3160
movl %r12d, %r14d
movq %r13, %rdi
callq 0x31c0
movq %rax, %r13
movq 0x8(%rsp), %rdi
cmpq %rbx, %rdi
je 0xf8a5
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3290
leaq 0x68(%rsp), %rax
cmpq %rax, %r13
jne 0xf7ec
testl %r15d, %r15d
setg %r14b
movl $0x1, %ecx
movq %rbp, %rdi
movq 0x50(%rsp), %rsi
movq (%rsp), %rdx
callq 0x32b0
movq 0xb8(%rsp), %r13
movq 0x30(%rsp), %r15
cmpq %r13, %r15
movq %r13, %rdx
cmovbq %r15, %rdx
testq %rdx, %rdx
je 0xf905
movq 0x28(%rsp), %rsi
movq 0xb0(%rsp), %rdi
callq 0x32a0
testl %eax, %eax
sete %al
jmp 0xf907
movb $0x1, %al
cmpq %r15, %r13
sete %cl
testb %cl, %al
jne 0xf98b
movq 0x10(%rsp), %r15
cmpq %r15, %r13
movq %r15, %rdx
cmovbq %r13, %rdx
testq %rdx, %rdx
je 0xf93e
movq 0xb0(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0x32a0
testl %eax, %eax
setne %al
jmp 0xf940
xorl %eax, %eax
cmpq %r13, %r15
setne %cl
orb %al, %cl
andb %r14b, %cl
cmpb $0x1, %cl
jne 0xf98b
movq 0xb0(%rsp), %rcx
movl $0x1, %edx
movq 0x50(%rsp), %rdi
movq (%rsp), %rsi
movq %r13, %r8
callq 0x32d0
movq 0x8(%rsp), %rcx
movq 0x10(%rsp), %r8
movl $0x1, %edx
movq 0x58(%rsp), %rdi
movq (%rsp), %rsi
callq 0x32d0
movq 0x8(%rsp), %rdi
cmpq %rbx, %rdi
je 0xf9a2
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
leaq 0x130(%rsp), %r14
je 0xf9c6
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0xb0(%rsp), %rdi
leaq 0xc0(%rsp), %rax
cmpq %rax, %rdi
movq 0x50(%rsp), %r15
je 0xf9f0
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x3290
leaq 0x60(%rsp), %rdi
callq 0x15fd2
movq (%rsp), %rcx
incq %rcx
movq %rcx, (%rsp)
cmpq 0x8(%r15), %rcx
jb 0xf5b5
movq 0x115c2(%rip), %rbx     # 0x20fd8
leaq 0xa330(%rip), %rsi      # 0x19d4d
movl $0x24, %edx
movq %rbx, %rdi
callq 0x32f0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x3260
movsbl %al, %esi
movq 0x11590(%rip), %rdi     # 0x20fd8
callq 0x3030
movq %rax, %rdi
callq 0x31b0
movq %rax, %rbx
leaq 0xa469(%rip), %rsi      # 0x19ec8
movl $0x1, %edx
movq %rax, %rdi
callq 0x32f0
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movq %rbx, %rdi
callq 0x32f0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x3260
movsbl %al, %esi
movq %rbx, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x31b0
movq %rax, %rbx
leaq 0xa419(%rip), %rsi      # 0x19ec8
movl $0x1, %edx
movq %rax, %rdi
callq 0x32f0
movq 0x58(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %rbx, %rdi
callq 0x32f0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x3260
movsbl %al, %esi
movq %rbx, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x31b0
leaq 0x128(%rsp), %rdi
callq 0x14e9a
movb $0x1, %al
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xfb1f
jmp 0xfb5c
movq %rax, %r14
jmp 0xfc23
jmp 0xfbbe
jmp 0xfc04
movq %rax, %r14
jmp 0xfbdd
movq %rax, %r14
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0xfb80
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3290
jmp 0xfb80
jmp 0xfb7d
movq %rax, %r14
movq 0x8(%rsp), %rdi
cmpq %rbx, %rdi
je 0xfbc1
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3290
jmp 0xfbc1
movq %rax, %r14
jmp 0xfba5
movq %rax, %r14
movq 0x90(%rsp), %rdi
leaq 0xa0(%rsp), %rax
cmpq %rax, %rdi
je 0xfba5
movq 0xa0(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0x8(%rsp), %rdi
cmpq %rbx, %rdi
je 0xfc0c
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3290
jmp 0xfc0c
movq %rax, %r14
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0xfbdd
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0xb0(%rsp), %rdi
leaq 0xc0(%rsp), %rax
cmpq %rax, %rdi
je 0xfc19
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x3290
jmp 0xfc19
movq %rax, %r14
jmp 0xfc19
movq %rax, %r14
leaq 0xb0(%rsp), %rdi
callq 0x14746
leaq 0x60(%rsp), %rdi
callq 0x15fd2
leaq 0x128(%rsp), %rdi
callq 0x14e9a
movq %r14, %rdi
callq 0x3460