// File: /workspace/github_cpp_makefile_star2_O3/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, %r13
movq %rsi, %rbx
movq %rdi, %rsi
leaq 0x128(%rsp), %r14
movq %r14, %rdi
callq 0x151e0
movq 0x18(%rbx), %rsi
addq $0x8, %rbx
movq %r14, %rdi
movq %rbx, %rdx
callq 0x179ba
cmpq $0x0, 0x8(%r13)
je 0xf8ff
leaq 0x18(%rsp), %r12
leaq 0xb0(%rsp), %r14
leaq 0x8(%rsp), %rbp
leaq 0x60(%rsp), %r15
movq $0x0, (%rsp)
movq %r13, 0x50(%rsp)
movl $0x0, 0x88(%rsp)
xorl %eax, %eax
movq %rax, 0x90(%rsp)
leaq 0x88(%rsp), %rbx
movq %rbx, 0x98(%rsp)
movq %rbx, 0xa0(%rsp)
movq %rax, 0xa8(%rsp)
movq 0x140(%rsp), %r13
leaq 0x130(%rsp), %rax
cmpq %rax, %r13
je 0xf681
leaq 0x130(%rsp), %rbx
leaq 0x28(%r13), %rsi
movq %r14, %rdi
callq 0x14816
movq %r12, 0x8(%rsp)
movq 0xb0(%rsp), %rsi
movq 0xb8(%rsp), %rdx
addq %rsi, %rdx
movq %rbp, %rdi
callq 0x164ba
movl $0x1, %ecx
movq %r15, %rdi
movq %rbp, %rsi
movq (%rsp), %rdx
callq 0x32b0
leaq 0x80(%rsp), %rdi
movq %r15, %rsi
callq 0x17b12
leaq 0x88(%rsp), %rcx
cmpq %rcx, %rax
je 0xf549
incl 0x40(%rax)
jmp 0xf5a6
leaq 0x38(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x60(%rsp), %rsi
movq 0x68(%rsp), %rdx
addq %rsi, %rdx
leaq 0x28(%rsp), %r15
movq %r15, %rdi
callq 0x164ba
movl $0x1, 0x48(%rsp)
leaq 0x80(%rsp), %rdi
movq %r15, %rsi
callq 0x17b9c
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0xf5a1
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3290
leaq 0x60(%rsp), %r15
movq %r13, %rdi
callq 0x31c0
movq %rax, %r13
movq 0x60(%rsp), %rdi
leaq 0x70(%rsp), %rax
cmpq %rax, %rdi
je 0xf5cd
movq 0x70(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0x8(%rsp), %rdi
cmpq %r12, %rdi
je 0xf5e4
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0x110(%rsp), %rdi
testq %rdi, %rdi
je 0xf601
movq 0x120(%rsp), %rsi
subq %rdi, %rsi
callq 0x3290
movq 0xf0(%rsp), %rdi
leaq 0x100(%rsp), %rax
cmpq %rax, %rdi
je 0xf626
movq 0x100(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0xd0(%rsp), %rdi
leaq 0xe0(%rsp), %rax
cmpq %rax, %rdi
je 0xf64b
movq 0xe0(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0xb0(%rsp), %rdi
leaq 0xc0(%rsp), %rax
cmpq %rax, %rdi
je 0xf670
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x3290
cmpq %rbx, %r13
jne 0xf4e7
movq 0x98(%rsp), %rbx
leaq 0xc0(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq %r14, %rdi
leaq 0xa82e(%rip), %r14      # 0x19ec9
movq %r14, %rsi
movq %r14, %rdx
callq 0x16550
leaq 0x38(%rsp), %rax
movq %rax, 0x28(%rsp)
leaq 0x28(%rsp), %rdi
movq %r14, %rsi
movq %r14, %rdx
callq 0x16550
xorl %r13d, %r13d
leaq 0x88(%rsp), %rax
cmpq %rax, %rbx
je 0xf7ad
xorl %r15d, %r15d
movq %r12, 0x8(%rsp)
movq 0x20(%rbx), %rsi
movq 0x28(%rbx), %rdx
addq %rsi, %rdx
movq %rbp, %rdi
callq 0x164ba
movl 0x40(%rbx), %r14d
movq %rbp, %rdi
leaq 0xa648(%rip), %rsi      # 0x19d45
callq 0x30b0
testl %eax, %eax
je 0xf73f
movq %rbp, %rdi
leaq 0xa637(%rip), %rsi      # 0x19d47
callq 0x30b0
testl %eax, %eax
je 0xf73f
movq %rbp, %rdi
leaq 0xa626(%rip), %rsi      # 0x19d49
callq 0x30b0
testl %eax, %eax
je 0xf73f
movq %rbp, %rdi
leaq 0xa615(%rip), %rsi      # 0x19d4b
callq 0x30b0
testl %eax, %eax
jne 0xf76e
cmpl %r15d, %r14d
jle 0xf759
leaq 0xb0(%rsp), %rdi
movq %rbp, %rsi
callq 0x3160
movl %r14d, %r15d
jmp 0xf76e
cmpl %r13d, %r14d
jl 0xf76e
leaq 0x28(%rsp), %rdi
movq %rbp, %rsi
callq 0x3160
movl %r14d, %r13d
movq %rbx, %rdi
callq 0x31c0
movq %rax, %rbx
movq 0x8(%rsp), %rdi
cmpq %r12, %rdi
je 0xf790
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3290
leaq 0x88(%rsp), %rax
cmpq %rax, %rbx
jne 0xf6d7
testl %r15d, %r15d
setg %r13b
leaq 0x60(%rsp), %r15
movl $0x1, %ecx
movq %rbp, %rdi
movq 0x50(%rsp), %rsi
movq (%rsp), %rdx
callq 0x32b0
movq 0xb8(%rsp), %rbx
movq 0x30(%rsp), %r14
cmpq %rbx, %r14
movq %rbx, %rdx
cmovbq %r14, %rdx
testq %rdx, %rdx
je 0xf7fc
movq 0x28(%rsp), %rsi
movq 0xb0(%rsp), %rdi
callq 0x32a0
cmpq %r14, %rbx
jne 0xf801
testl %eax, %eax
je 0xf878
jmp 0xf801
cmpq %r14, %rbx
je 0xf878
movq 0x10(%rsp), %r14
cmpq %r14, %rbx
movq %r14, %rdx
cmovbq %rbx, %rdx
testq %rdx, %rdx
je 0xf832
movq 0xb0(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0x32a0
testl %eax, %eax
je 0xf832
testb %r13b, %r13b
jne 0xf83d
jmp 0xf878
cmpq %rbx, %r14
setne %al
testb %r13b, %al
je 0xf878
movq 0xb0(%rsp), %rcx
movl $0x1, %edx
movq 0x50(%rsp), %rdi
movq (%rsp), %rsi
movq %rbx, %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 %r12, %rdi
je 0xf88f
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
leaq 0xb0(%rsp), %r14
je 0xf8b3
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0xb0(%rsp), %rdi
leaq 0xc0(%rsp), %rax
cmpq %rax, %rdi
movq 0x50(%rsp), %r13
je 0xf8dd
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x3290
leaq 0x80(%rsp), %rdi
callq 0x15efc
movq (%rsp), %rcx
incq %rcx
movq %rcx, (%rsp)
cmpq 0x8(%r13), %rcx
jb 0xf491
movq 0x116d2(%rip), %rbx     # 0x20fd8
leaq 0xa440(%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 0x116a0(%rip), %rdi     # 0x20fd8
callq 0x3030
movq %rax, %rdi
callq 0x31b0
movq %rax, %rbx
leaq 0xa579(%rip), %rsi      # 0x19ec8
movl $0x1, %edx
movq %rax, %rdi
callq 0x32f0
movq (%r13), %rsi
movq 0x8(%r13), %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 0xa528(%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 0x14dc6
movb $0x1, %al
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xfa10
jmp 0xfa47
movq %rax, %rbx
jmp 0xfb08
jmp 0xfa63
jmp 0xfaf8
movq %rax, %rbx
jmp 0xfa82
movq %rax, %rbx
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0xfaac
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3290
jmp 0xfaac
jmp 0xfaa9
movq %rax, %rbx
movq 0x8(%rsp), %rdi
cmpq %r12, %rdi
je 0xfa66
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3290
jmp 0xfa66
movq %rax, %rbx
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0xfa82
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3290
movq 0xb0(%rsp), %rdi
leaq 0xc0(%rsp), %rax
cmpq %rax, %rdi
je 0xfafb
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x3290
jmp 0xfafb
movq %rax, %rbx
movq 0x60(%rsp), %rdi
leaq 0x70(%rsp), %rax
cmpq %rax, %rdi
je 0xfacd
movq 0x70(%rsp), %rsi
incq %rsi
callq 0x3290
jmp 0xfacd
movq %rax, %rbx
movq 0x8(%rsp), %rdi
cmpq %r12, %rdi
je 0xfae9
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3290
jmp 0xfae9
movq %rax, %rbx
leaq 0xb0(%rsp), %rdi
callq 0x1466e
jmp 0xfafb
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x15efc
leaq 0x128(%rsp), %rdi
callq 0x14dc6
movq %rbx, %rdi
callq 0x3460