// File: /workspace/github_cpp_makefile_star2_O2/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, (%rsp)
movq %rdx, %r15
movq %rsi, %rbx
movq %rdi, %rsi
leaq 0xb0(%rsp), %r14
movq %r14, %rdi
callq 0xea50
movq 0x18(%rbx), %rsi
addq $0x8, %rbx
movq %r14, %rdi
movq %rbx, %rdx
callq 0x110fa
xorl %r14d, %r14d
leaq 0xe0(%rsp), %r13
leaq 0x48(%rsp), %r12
leaq 0x90(%rsp), %rbx
movq %r15, 0x40(%rsp)
cmpq 0x8(%r15), %r14
jae 0xad48
movq %r14, 0x8(%rsp)
andl $0x0, 0x18(%rsp)
andq $0x0, 0x20(%rsp)
leaq 0x18(%rsp), %rax
movq %rax, 0x28(%rsp)
movq %rax, 0x30(%rsp)
andq $0x0, 0x38(%rsp)
movq 0xc8(%rsp), %r14
leaq 0xb8(%rsp), %rax
cmpq %rax, %r14
je 0xabd9
leaq 0x28(%r14), %rsi
movq %r13, %rdi
callq 0xe396
movq %rbx, %rdi
movq %r13, %rsi
callq 0x3300
leaq 0x70(%rsp), %rbp
movq %rbp, %rdi
movq %rbx, %rsi
movq 0x8(%rsp), %rdx
pushq $0x1
popq %rcx
callq 0x3290
leaq 0x10(%rsp), %rdi
movq %rbp, %rsi
callq 0x1125a
leaq 0x18(%rsp), %rcx
cmpq %rcx, %rax
je 0xab85
incl 0x40(%rax)
jmp 0xabaf
movq %r12, %rdi
leaq 0x70(%rsp), %rsi
callq 0x3300
movl $0x1, 0x68(%rsp)
leaq 0x10(%rsp), %rdi
movq %r12, %rsi
callq 0x112d0
movq %r12, %rdi
callq 0x3120
movq %r14, %rdi
callq 0x31c0
movq %rax, %r14
leaq 0x70(%rsp), %rdi
callq 0x3120
movq %rbx, %rdi
callq 0x3120
movq %r13, %rdi
callq 0xe2b0
jmp 0xab29
movq 0x28(%rsp), %r14
movq %r13, %rdi
movq %r12, %rbp
leaq 0x92dc(%rip), %r12      # 0x13ec7
movq %r12, %rsi
movq %rbp, %rdx
callq 0xe174
movq %rbp, %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0xe174
xorl %r12d, %r12d
xorl %r15d, %r15d
leaq 0x18(%rsp), %rax
cmpq %rax, %r14
je 0xacb6
leaq 0x20(%r14), %rsi
movq %rbx, %rdi
callq 0x3300
movl 0x40(%r14), %ebp
movq %rbx, %rdi
leaq 0x9111(%rip), %rsi      # 0x13d43
callq 0x30c0
testl %eax, %eax
je 0xac74
movq %rbx, %rdi
leaq 0x9100(%rip), %rsi      # 0x13d45
callq 0x30c0
testl %eax, %eax
je 0xac74
movq %rbx, %rdi
leaq 0x90ef(%rip), %rsi      # 0x13d47
callq 0x30c0
testl %eax, %eax
je 0xac74
movq %rbx, %rdi
leaq 0x90de(%rip), %rsi      # 0x13d49
callq 0x30c0
testl %eax, %eax
jne 0xac9e
cmpl %r12d, %ebp
jle 0xac89
movq %r13, %rdi
movq %rbx, %rsi
callq 0x3170
movl %ebp, %r12d
jmp 0xac9e
cmpl %r15d, %ebp
jl 0xac9e
leaq 0x48(%rsp), %rdi
movq %rbx, %rsi
callq 0x3170
movl %ebp, %r15d
movq %r14, %rdi
callq 0x31c0
movq %rax, %r14
movq %rbx, %rdi
callq 0x3120
jmp 0xac0a
movq %rbx, %rdi
movq 0x40(%rsp), %r15
movq %r15, %rsi
movq 0x8(%rsp), %r14
movq %r14, %rdx
pushq $0x1
popq %rcx
callq 0x3290
movq %r13, %rdi
leaq 0x48(%rsp), %rsi
callq 0x3030
testl %eax, %eax
je 0xad19
movq %rbx, %rdi
movq %r13, %rsi
callq 0x3030
testl %eax, %eax
je 0xad19
testl %r12d, %r12d
jle 0xad19
movq %r15, %rdi
movq %r14, %rsi
pushq $0x1
popq %rdx
movq %r13, %rcx
callq 0x30f0
movq (%rsp), %rdi
movq %r14, %rsi
pushq $0x1
popq %rdx
movq %rbx, %rcx
callq 0x30f0
movq %rbx, %rdi
callq 0x3120
leaq 0x48(%rsp), %r12
movq %r12, %rdi
callq 0x3120
movq %r13, %rdi
callq 0x3120
leaq 0x10(%rsp), %rdi
callq 0xf728
incq %r14
jmp 0xaaf2
movq 0x11289(%rip), %rdi     # 0x1bfd8
leaq 0x8ff5(%rip), %rsi      # 0x13d4b
callq 0x3260
movq %rax, %rdi
callq 0x3140
leaq 0x915c(%rip), %rsi      # 0x13ec6
movq %rax, %rdi
callq 0x3260
movq %rax, %rdi
movq %r15, %rsi
callq 0x3240
movq %rax, %rdi
callq 0x3140
leaq 0x913a(%rip), %rsi      # 0x13ec6
movq %rax, %rdi
callq 0x3260
movq %rax, %rdi
movq (%rsp), %rsi
callq 0x3240
movq %rax, %rdi
callq 0x3140
leaq 0xb0(%rsp), %rdi
callq 0xe6da
movb $0x1, %al
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xadcb
movq %rax, %rbx
jmp 0xae5d
jmp 0xae01
jmp 0xae1d
movq %rax, %rbx
jmp 0xae0e
jmp 0xadef
jmp 0xae2c
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0x3120
jmp 0xae2f
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x3120
jmp 0xae04
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0x3120
leaq 0xe0(%rsp), %rdi
callq 0x3120
jmp 0xae53
movq %rax, %rbx
jmp 0xae53
movq %rax, %rbx
jmp 0xae46
movq %rax, %rbx
jmp 0xae39
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x3120
leaq 0x90(%rsp), %rdi
callq 0x3120
leaq 0xe0(%rsp), %rdi
callq 0xe2b0
leaq 0x10(%rsp), %rdi
callq 0xf728
leaq 0xb0(%rsp), %rdi
callq 0xe6da
movq %rbx, %rdi
callq 0x3410