// File: schneebergerlab[P]GameteBinning/asPollinator_1.0.cpp
// Function: cluster_pollens(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::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::map<int, POLLEN, std::less<int>, std::allocator<std::pair<int const, POLLEN>>>*)
bool cluster_pollens(map<int, POLLEN>  pollens, 
                     map<int, POLLEN>* maCluster,
                     map<int, POLLEN>* paCluster,
                     map<int, POLLEN>* unCluster,
                     map<int, POLLEN>* pollens_updated)
{
    // idea: using initial haplotypes related to a contig as backbone, 
    //       1.color   pollen genotypes
    //       2.cluster pollen genotypes
    //       3.correct haplotypes
    assert(pollens.find(0) != pollens.end());
    string matGT = pollens[0].poSeq; // maternal backbone
    string patGT = pollens[0].poAll; // paternal backbone
    //
    // map<int, POLLEN> maCluster; // close to maternal GT
    // map<int, POLLEN> paCluster; // close to paternal GT
    // map<int, POLLEN> unCluster; // not informative 
    //
    map<int, POLLEN>::iterator pollenitr;
    map<int, POLLEN>::iterator pollenitr_end;
    pollenitr        = pollens.begin();
    pollenitr_end    = pollens.end();
    while(pollenitr != pollenitr_end)
    {
        int     pid  = (*pollenitr).first;
        POLLEN ptmp  = (*pollenitr).second;
        if(pid>0)
        {
            string        pollenGT = ((*pollenitr).second).poSeq;
            string        pattern  = "";                   
            unsigned long matscore = 0; 
            unsigned long patscore = 0;
            if( !get_similarty(matGT,
                               patGT,
                               pollenGT,
                               &pattern,
                               &matscore,
                               &patscore) )
            {
                return false;
            }
            // updating attribute pattern of pollen
            ((*pollenitr).second).poPat = pattern;
            // setting  attribute pattern of pollen
            ptmp.poPat = pattern;  
            //
            if(matscore  > patscore)
            {
                (*maCluster).insert(std::pair<int, POLLEN>(pid, ptmp));
            }
            else
            if(matscore  < patscore)
            {
                (*paCluster).insert(std::pair<int, POLLEN>(pid, ptmp));
            }else
            if(matscore == patscore)
            {
                (*unCluster).insert(std::pair<int, POLLEN>(pid, ptmp));
            }else ;
        }
        pollenitr ++;
    }
    // get pattern inserted in pollen data - new
    (*pollens_updated) = pollens;
    //
    return true;
}

// Assembly:
subq $0x438, %rsp            # imm = 0x438
movq %rdi, 0x70(%rsp)
movq %rdi, 0x428(%rsp)
movq %rsi, 0x420(%rsp)
movq %rdx, 0x418(%rsp)
movq %rcx, 0x410(%rsp)
movq %r8, 0x408(%rsp)
movl $0x0, 0x3fc(%rsp)
leaq 0x3fc(%rsp), %rsi
callq 0x1a900
movq 0x70(%rsp), %rdi
movq %rax, 0x400(%rsp)
callq 0x19250
movq %rax, 0x3f0(%rsp)
leaq 0x400(%rsp), %rdi
leaq 0x3f0(%rsp), %rsi
callq 0x19280
testb $0x1, %al
jne 0x10d31
jmp 0x10d33
jmp 0x10d52
leaq 0x1b29c(%rip), %rdi     # 0x2bfd6
leaq 0x1ad22(%rip), %rsi     # 0x2ba63
movl $0x98e, %edx            # imm = 0x98E
leaq 0x1b2aa(%rip), %rcx     # 0x2bff7
callq 0x3210
movq 0x70(%rsp), %rdi
movl $0x0, 0x3cc(%rsp)
leaq 0x3cc(%rsp), %rsi
callq 0x19010
movq %rax, %rsi
leaq 0x3d0(%rsp), %rdi
callq 0x3160
movq 0x70(%rsp), %rdi
movl $0x0, 0x3a4(%rsp)
leaq 0x3a4(%rsp), %rsi
callq 0x19010
movq %rax, 0x68(%rsp)
jmp 0x10da3
movq 0x68(%rsp), %rsi
addq $0x20, %rsi
leaq 0x3a8(%rsp), %rdi
callq 0x3160
jmp 0x10dbb
leaq 0x388(%rsp), %rdi
callq 0x19200
leaq 0x380(%rsp), %rdi
callq 0x19200
movq 0x70(%rsp), %rdi
callq 0x19220
movq 0x70(%rsp), %rdi
movq %rax, 0x378(%rsp)
movq 0x378(%rsp), %rax
movq %rax, 0x388(%rsp)
callq 0x19250
movq %rax, 0x370(%rsp)
movq 0x370(%rsp), %rax
movq %rax, 0x380(%rsp)
leaq 0x388(%rsp), %rdi
leaq 0x380(%rsp), %rsi
callq 0x19280
testb $0x1, %al
jne 0x10e37
jmp 0x113a5
leaq 0x388(%rsp), %rdi
movq %rdi, 0x60(%rsp)
callq 0x192a0
movq 0x60(%rsp), %rdi
movl (%rax), %eax
movl %eax, 0x36c(%rsp)
callq 0x192a0
movq %rax, %rsi
addq $0x8, %rsi
leaq 0x2f0(%rsp), %rdi
callq 0x192c0
jmp 0x10e72
cmpl $0x0, 0x36c(%rsp)
jle 0x11358
leaq 0x388(%rsp), %rdi
callq 0x192a0
movq %rax, %rsi
addq $0x8, %rsi
leaq 0x2d0(%rsp), %rdi
callq 0x3160
jmp 0x10ea3
leaq 0x2af(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0x3570
movq 0x58(%rsp), %rdx
leaq 0x1afa0(%rip), %rsi     # 0x2be61
leaq 0x2b0(%rsp), %rdi
callq 0x185e0
jmp 0x10ed0
leaq 0x2af(%rsp), %rdi
callq 0x3390
movq $0x0, 0x2a0(%rsp)
movq $0x0, 0x298(%rsp)
leaq 0x278(%rsp), %rdi
leaq 0x3d0(%rsp), %rsi
callq 0x3160
jmp 0x10f0c
leaq 0x258(%rsp), %rdi
leaq 0x3a8(%rsp), %rsi
callq 0x3160
jmp 0x10f23
leaq 0x238(%rsp), %rdi
leaq 0x2d0(%rsp), %rsi
callq 0x3160
jmp 0x10f3a
leaq 0x278(%rsp), %rdi
leaq 0x258(%rsp), %rsi
leaq 0x238(%rsp), %rdx
leaq 0x2b0(%rsp), %rcx
leaq 0x2a0(%rsp), %r8
leaq 0x298(%rsp), %r9
callq 0x182a0
movb %al, 0x57(%rsp)
jmp 0x10f75
movb 0x57(%rsp), %al
xorb $-0x1, %al
movb %al, 0x56(%rsp)
leaq 0x238(%rsp), %rdi
callq 0x31e0
leaq 0x258(%rsp), %rdi
callq 0x31e0
leaq 0x278(%rsp), %rdi
callq 0x31e0
movb 0x56(%rsp), %al
testb $0x1, %al
jne 0x10fb3
jmp 0x110c1
movb $0x0, 0x437(%rsp)
movl $0x1, 0x234(%rsp)
jmp 0x11313
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x398(%rsp)
movl %eax, 0x394(%rsp)
jmp 0x11404
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x398(%rsp)
movl %eax, 0x394(%rsp)
jmp 0x113f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x398(%rsp)
movl %eax, 0x394(%rsp)
jmp 0x11396
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x398(%rsp)
movl %eax, 0x394(%rsp)
leaq 0x2af(%rsp), %rdi
callq 0x3390
jmp 0x11349
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x398(%rsp)
movl %eax, 0x394(%rsp)
jmp 0x1133c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x398(%rsp)
movl %eax, 0x394(%rsp)
jmp 0x110af
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x398(%rsp)
movl %eax, 0x394(%rsp)
jmp 0x110a2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x398(%rsp)
movl %eax, 0x394(%rsp)
leaq 0x238(%rsp), %rdi
callq 0x31e0
leaq 0x258(%rsp), %rdi
callq 0x31e0
leaq 0x278(%rsp), %rdi
callq 0x31e0
jmp 0x1133c
leaq 0x388(%rsp), %rdi
callq 0x192a0
movq %rax, %rdi
addq $0x48, %rdi
leaq 0x2b0(%rsp), %rsi
callq 0x3050
jmp 0x110e4
leaq 0x330(%rsp), %rdi
leaq 0x2b0(%rsp), %rsi
callq 0x3050
jmp 0x110fb
movq 0x2a0(%rsp), %rax
cmpq 0x298(%rsp), %rax
jbe 0x111aa
movq 0x420(%rsp), %rax
movq %rax, 0x48(%rsp)
leaq 0x1b0(%rsp), %rdi
leaq 0x36c(%rsp), %rsi
leaq 0x2f0(%rsp), %rdx
callq 0x18bf0
jmp 0x1113d
movq 0x48(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
callq 0x18ba0
movb %dl, 0x3f(%rsp)
movq %rax, 0x40(%rsp)
jmp 0x1115a
movb 0x3f(%rsp), %al
movq 0x40(%rsp), %rcx
movq %rcx, 0x1a0(%rsp)
movb %al, 0x1a8(%rsp)
leaq 0x1b0(%rsp), %rdi
callq 0x18c30
jmp 0x11308
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x398(%rsp)
movl %eax, 0x394(%rsp)
leaq 0x1b0(%rsp), %rdi
callq 0x18c30
jmp 0x1133c
movq 0x2a0(%rsp), %rax
cmpq 0x298(%rsp), %rax
jae 0x11259
movq 0x418(%rsp), %rax
movq %rax, 0x30(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x36c(%rsp), %rsi
leaq 0x2f0(%rsp), %rdx
callq 0x18bf0
jmp 0x111ec
movq 0x30(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x18ba0
movb %dl, 0x27(%rsp)
movq %rax, 0x28(%rsp)
jmp 0x11209
movb 0x27(%rsp), %al
movq 0x28(%rsp), %rcx
movq %rcx, 0x110(%rsp)
movb %al, 0x118(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x18c30
jmp 0x11306
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x398(%rsp)
movl %eax, 0x394(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x18c30
jmp 0x1133c
movq 0x2a0(%rsp), %rax
cmpq 0x298(%rsp), %rax
jne 0x11302
movq 0x410(%rsp), %rax
movq %rax, 0x18(%rsp)
leaq 0x90(%rsp), %rdi
leaq 0x36c(%rsp), %rsi
leaq 0x2f0(%rsp), %rdx
callq 0x18bf0
jmp 0x1129b
movq 0x18(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x18ba0
movb %dl, 0xf(%rsp)
movq %rax, 0x10(%rsp)
jmp 0x112b8
movb 0xf(%rsp), %al
movq 0x10(%rsp), %rcx
movq %rcx, 0x80(%rsp)
movb %al, 0x88(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x18c30
jmp 0x11304
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x398(%rsp)
movl %eax, 0x394(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x18c30
jmp 0x1133c
jmp 0x11304
jmp 0x11306
jmp 0x11308
movl $0x0, 0x234(%rsp)
leaq 0x2b0(%rsp), %rdi
callq 0x31e0
leaq 0x2d0(%rsp), %rdi
callq 0x31e0
movl 0x234(%rsp), %eax
testl %eax, %eax
jne 0x11377
jmp 0x1133a
jmp 0x11358
leaq 0x2b0(%rsp), %rdi
callq 0x31e0
leaq 0x2d0(%rsp), %rdi
callq 0x31e0
jmp 0x11396
leaq 0x388(%rsp), %rdi
xorl %esi, %esi
callq 0x193a0
movq %rax, 0x78(%rsp)
movl $0x0, 0x234(%rsp)
leaq 0x2f0(%rsp), %rdi
callq 0x18df0
movl 0x234(%rsp), %eax
testl %eax, %eax
jne 0x113cc
jmp 0x11391
jmp 0x10e19
leaq 0x2f0(%rsp), %rdi
callq 0x18df0
jmp 0x113f7
movq 0x70(%rsp), %rsi
movq 0x408(%rsp), %rdi
callq 0x193e0
jmp 0x113b9
movb $0x1, 0x437(%rsp)
movl $0x1, 0x234(%rsp)
leaq 0x3a8(%rsp), %rdi
callq 0x31e0
leaq 0x3d0(%rsp), %rdi
callq 0x31e0
movb 0x437(%rsp), %al
andb $0x1, %al
addq $0x438, %rsp            # imm = 0x438
retq
leaq 0x3a8(%rsp), %rdi
callq 0x31e0
leaq 0x3d0(%rsp), %rdi
callq 0x31e0
movq 0x398(%rsp), %rdi
callq 0x3560
nop