// File: /workspace/github_cpp_makefile_star2_O2/millanek[P]evo/process_vcf_stats_functions.cpp
// Function: doubleton_analysis(std::vector<std::vector<int, std::allocator<int>>, std::allocator<std::vector<int, std::allocator<int>>>>&, FilterResult&, int, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, int>>>&)
void doubleton_analysis(std::vector<std::vector<int> >& doubletons, FilterResult& result, int numChromosomes, const std::vector<std::string> p, std::map<std::string,int>& p_int_map) {
#ifdef TESTING
    std::cerr << "Overall count: " << result.counts.overall << std::endl;
#endif
    int fields[2];
    
    if (result.counts.overall == 2) {
        std::vector<int>::iterator it_hom;
        std::vector<int>::iterator it_het;
        // Check if the doubleton is in a single homozygous individual
        it_hom = std::find(result.counts.individualsWithVariant.begin(), result.counts.individualsWithVariant.end(), 2);
        if (it_hom != result.counts.individualsWithVariant.end()) {
            int doubleton_hom = (int)std::distance(result.counts.individualsWithVariant.begin(), it_hom);
            fields[0] = doubleton_hom; fields[1] = doubleton_hom;
        } else {
            // Otherwise look at which two individuals have the two heterozygous variants
            it_het = std::find(result.counts.individualsWithVariant.begin(), result.counts.individualsWithVariant.end(), 1);
            int i = 0;
            while (it_het != result.counts.individualsWithVariant.end()) {
                int doubleton_het = (int)std::distance(result.counts.individualsWithVariant.begin(), it_het);
                fields[i] = doubleton_het;
                ++it_het;
                it_het = std::find(it_het, result.counts.individualsWithVariant.end(), 1);
                ++i;
            }
            assert(i <= 3);
        }
#ifdef TESTING
        std::cerr << "Fields 0: " << fields[0] << " Fields 1: " << fields[1] << std::endl;
        std::cerr << "pop1: " << p[fields[0]] << " pop 2: " << p[fields[1]] << std::endl;
#endif
        doubletons[p_int_map[p[fields[0]]]][p_int_map[p[fields[1]]]]++;
    }
    if (result.counts.overall == (numChromosomes - 2)) {
        std::vector<int>::iterator it_hom;
        std::vector<int>::iterator it_het;
        // Check if the doubleton is in a single homozygous individual
        it_hom = std::find(result.counts.individualsWithVariant.begin(), result.counts.individualsWithVariant.end(), 0);
        if (it_hom != result.counts.individualsWithVariant.end()) {
            int doubleton_hom = (int)std::distance(result.counts.individualsWithVariant.begin(), it_hom);
            fields[0] = doubleton_hom; fields[1] = doubleton_hom;
        } else {
            // Otherwise look at which two individuals have the two heterozygous variants
            it_het = std::find(result.counts.individualsWithVariant.begin(), result.counts.individualsWithVariant.end(), 1);
            int i = 0;
            while (it_het != result.counts.individualsWithVariant.end()) {
                int doubleton_het = (int)std::distance(result.counts.individualsWithVariant.begin(), it_het);
                fields[i] = doubleton_het;
                ++it_het;
                it_het = std::find(it_het, result.counts.individualsWithVariant.end(), 1);
                ++i;
            }
            assert(i <= 3);
        }
#ifdef TESTING
        std::cerr << "Fields 0: " << fields[0] << " Fields 1: " << fields[1] << std::endl;
        std::cerr << "pop1: " << p[fields[0]] << " pop 2: " << p[fields[1]] << std::endl;
#endif
        doubletons[p_int_map[p[fields[0]]]][p_int_map[p[fields[1]]]]++;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r8, %rbx
movq %rcx, %r14
movl %edx, %ebp
movq %rsi, %r12
movq %rdi, %r15
movl 0x8(%rsi), %eax
cmpl $0x2, %eax
jne 0x4be96
movq 0x78(%r12), %rdi
movq 0x80(%r12), %rsi
leaq 0x10(%rsp), %rdx
movl $0x2, (%rdx)
callq 0x451ef
movq 0x78(%r12), %rdi
movq 0x80(%r12), %rsi
cmpq %rsi, %rax
movl %ebp, 0x24(%rsp)
je 0x4bddc
movq %rax, %r13
subq %rdi, %r13
shrq $0x2, %r13
movl %r13d, 0x10(%rsp)
movl %r13d, 0x14(%rsp)
movl %r13d, %eax
jmp 0x4be4b
movq %r15, 0x18(%rsp)
leaq 0x10(%rsp), %rdx
movl $0x1, (%rdx)
callq 0x451ef
xorl %r15d, %r15d
leaq 0xc(%rsp), %r13
movq 0x80(%r12), %rsi
cmpq %rsi, %rax
je 0x4be33
movq %rax, %rcx
subq 0x78(%r12), %rcx
shrq $0x2, %rcx
movl %ecx, 0x10(%rsp,%r15,4)
addq $0x4, %rax
movl $0x1, 0xc(%rsp)
movq %rax, %rdi
movq %r13, %rdx
callq 0x451ef
incq %r15
jmp 0x4bdf9
cmpq $0x3, %r15
ja 0x4bf8a
movl 0x10(%rsp), %eax
movl 0x14(%rsp), %r13d
movq 0x18(%rsp), %r15
movslq %eax, %rsi
shlq $0x5, %rsi
addq (%r14), %rsi
movq %rbx, %rdi
callq 0x32a8a
movslq (%rax), %rax
movq (%r15), %rcx
movq %rcx, 0x18(%rsp)
imulq $0x18, %rax, %rbp
movslq %r13d, %rsi
shlq $0x5, %rsi
addq (%r14), %rsi
movq %rbx, %rdi
callq 0x32a8a
movslq (%rax), %rax
movq 0x18(%rsp), %rcx
movq (%rcx,%rbp), %rcx
incl (%rcx,%rax,4)
movl 0x8(%r12), %eax
movl 0x24(%rsp), %ebp
addl $-0x2, %ebp
cmpl %ebp, %eax
jne 0x4bf7b
movq 0x78(%r12), %rdi
movq 0x80(%r12), %rsi
leaq 0xc(%rsp), %rdx
andl $0x0, (%rdx)
callq 0x451ef
movq 0x78(%r12), %rdi
movq 0x80(%r12), %rsi
cmpq %rsi, %rax
je 0x4bedc
movq %rax, %r13
subq %rdi, %r13
shrq $0x2, %r13
movl %r13d, %eax
jmp 0x4bf43
movq %r15, %rbp
leaq 0xc(%rsp), %r13
movl $0x1, (%r13)
movq %r13, %rdx
callq 0x451ef
xorl %r15d, %r15d
movq 0x80(%r12), %rsi
cmpq %rsi, %rax
je 0x4bf31
movq %rax, %rcx
subq 0x78(%r12), %rcx
shrq $0x2, %rcx
movl %ecx, 0x10(%rsp,%r15,4)
addq $0x4, %rax
movl $0x1, 0xc(%rsp)
movq %rax, %rdi
movq %r13, %rdx
callq 0x451ef
incq %r15
jmp 0x4bef7
cmpq $0x3, %r15
ja 0x4bfa9
movl 0x10(%rsp), %eax
movl 0x14(%rsp), %r13d
movq %rbp, %r15
movslq %eax, %rsi
shlq $0x5, %rsi
addq (%r14), %rsi
movq %rbx, %rdi
callq 0x32a8a
movslq (%rax), %rax
movq %rbx, %rdi
movq (%r15), %rbx
imulq $0x18, %rax, %r15
movslq %r13d, %rsi
shlq $0x5, %rsi
addq (%r14), %rsi
callq 0x32a8a
movslq (%rax), %rax
movq (%rbx,%r15), %rcx
incl (%rcx,%rax,4)
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x55447(%rip), %rdi     # 0xa13d8
leaq 0x55447(%rip), %rsi     # 0xa13df
leaq 0x55460(%rip), %rcx     # 0xa13ff
movl $0x8c, %edx
callq 0x82f0
leaq 0x55428(%rip), %rdi     # 0xa13d8
leaq 0x55428(%rip), %rsi     # 0xa13df
leaq 0x55441(%rip), %rcx     # 0xa13ff
movl $0xa7, %edx
callq 0x82f0