// File: millanek[P]Dsuite/Dsuite_utils.cpp
// Function: GeneralSetCountsWithSplits::getAFsFromGenotypeLikelihoodsOrProbabilitiesWithSplits(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>>>> const&, std::map<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>> const&, int, int)
void GeneralSetCountsWithSplits::getAFsFromGenotypeLikelihoodsOrProbabilitiesWithSplits(const std::vector<std::string>& genotypeFields, const std::map<size_t, string>& posToSpeciesMap, const int likelihoodsOrProbabilitiesTagPosition, const int pos) {
   
    
    if (likelihoodsProbabilitiesType == LikelihoodsProbabilitiesPL || likelihoodsProbabilitiesType == LikelihoodsProbabilitiesGL) {
        setHWEpriorsFromAFfromGT();
    }
    
    getBasicCountsFromLikelihoodsOrProbabilities(genotypeFields, posToSpeciesMap, likelihoodsOrProbabilitiesTagPosition);
    
     
    // Now fill in the allele frequencies
    for(std::map<string,std::vector<double>>::iterator it = setIndividualExpectedGenotypes.begin(); it != setIndividualExpectedGenotypes.end(); ++it) {
        if (it->first == "") {
            std::cerr << "it->first " << it->first << "\t"; print_vector(it->second, std::cerr); std::cerr << std::endl;
        }
        std::vector<double> thisSetExpectedGenotypes = it->second;
        
        
        if (thisSetExpectedGenotypes.size() > 0) {
            double thisAAF = (double)vector_sum(thisSetExpectedGenotypes)/(2*thisSetExpectedGenotypes.size());
          /* Debug stuff
           if(pos == 1180 || pos == 1046) {
                std::cerr << "pos: " << pos << std::endl;
                std::cerr << "it->first: " << it->first << std::endl;
                print_vector(thisSetExpectedGenotypes, std::cerr);
                std::cerr << "thisAAF: " << thisAAF << std::endl;
            }
           */
            //std::cerr << "species: " << it->first << std::endl;
            // print_vector(thisSetExpectedGenotypes, std::cerr);
            // std::cerr << "thisAAF: " << thisAAF << std::endl;
            setAAFsFromLikelihoods.at(it->first) = thisAAF;
            
            // Take care of the splits by random sampling with replacement:
            std::random_device rd;     // only used once to initialise (seed) engine
            std::mt19937 rng(rd());    // random-number engine used (Mersenne-Twister in this case)
            std::uniform_int_distribution<int> uniAFs(0,((int)thisSetExpectedGenotypes.size() - 1)); // guaranteed unbiased
            
            
            std::vector<double> thisSetIndividualExpectedGenotypesSampledSplit1;
            std::vector<double> thisSetIndividualExpectedGenotypesSampledSplit2;
            for (int i = 0; i < thisSetExpectedGenotypes.size(); i++) {
                int random_pos_s1 = uniAFs(rng);
                int random_pos_s2 = uniAFs(rng);
                thisSetIndividualExpectedGenotypesSampledSplit1.push_back(thisSetExpectedGenotypes[random_pos_s1]);
                thisSetIndividualExpectedGenotypesSampledSplit2.push_back(thisSetExpectedGenotypes[random_pos_s2]);
            }
            
            double thisAAFsplit1 = (double)vector_sum(thisSetIndividualExpectedGenotypesSampledSplit1)/(2*thisSetExpectedGenotypes.size());
           // std::cerr << "thisAAFsplit1: " << thisAAFsplit1 << std::endl;
            double thisAAFsplit2 = (double)vector_sum(thisSetIndividualExpectedGenotypesSampledSplit2)/(2*thisSetExpectedGenotypes.size());
           // std::cerr << "thisAAFsplit2: " << thisAAFsplit2 << std::endl;

            
           // std::cerr << "it->first " << it->first << std::endl;
            try {
            setAAFsplit1fromLikelihoods.at(it->first) = thisAAFsplit1; setAAFsplit2fromLikelihoods.at(it->first) = thisAAFsplit2;
                
            if (AAint == AncestralAlleleRef) { // Ancestral allele seems to be the ref, so derived is alt
                setDAFsFromLikelihoods.at(it->first) = thisAAF;
                setDAFsplit1fromLikelihoods.at(it->first) = thisAAFsplit1;
                setDAFsplit2fromLikelihoods.at(it->first) = thisAAFsplit2;
            } else if (AAint == AncestralAlleleAlt) { // Ancestral allele seems to be alt, so derived is ref
                setDAFsFromLikelihoods.at(it->first) = (1 - thisAAF);
                setDAFsplit1fromLikelihoods.at(it->first) = 1 - thisAAFsplit1;
                setDAFsplit2fromLikelihoods.at(it->first) = 1 - thisAAFsplit2;
            }
            } catch (std::out_of_range& e) { std::cerr << "The trouble was here" << it->first << std::endl; }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2990, %rsp           # imm = 0x2990
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x2838(%rbp)
cmpl $0x3, 0x2e0(%rax)
je 0xd262
movq -0x2838(%rbp), %rax
cmpl $0x2, 0x2e0(%rax)
jne 0xd26e
movq -0x2838(%rbp), %rdi
callq 0xb430
movq -0x2838(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movl -0x1c(%rbp), %ecx
callq 0xdbe0
movq -0x2838(%rbp), %rdi
addq $0x68, %rdi
callq 0x11340
movq %rax, -0x28(%rbp)
movq -0x2838(%rbp), %rdi
addq $0x68, %rdi
callq 0x113a0
movq %rax, -0x30(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x11370
testb $0x1, %al
jne 0xd2c3
jmp 0xdbbe
leaq -0x28(%rbp), %rdi
callq 0x113d0
movq %rax, %rdi
leaq 0x7e093(%rip), %rsi     # 0x8b369
callq 0x9ab0
testb $0x1, %al
jne 0xd2e4
jmp 0xd3ad
movq 0xb1d05(%rip), %rdi     # 0xbeff0
movq %rdi, -0x2840(%rbp)
leaq 0x7b3b9(%rip), %rsi     # 0x886b2
callq 0x8590
movq %rax, -0x2858(%rbp)
leaq -0x28(%rbp), %rdi
movq %rdi, -0x2850(%rbp)
callq 0x113d0
movq -0x2858(%rbp), %rdi
movq %rax, %rsi
callq 0x8520
movq %rax, %rdi
leaq 0x7e03a(%rip), %rsi     # 0x8b368
callq 0x8590
movq -0x2850(%rbp), %rdi
callq 0x113d0
movq %rax, %rsi
addq $0x20, %rsi
leaq -0x48(%rbp), %rdi
movq %rdi, -0x2848(%rbp)
callq 0x110a0
movq -0x2848(%rbp), %rdi
movq -0x2840(%rbp), %rsi
movl $0x9, %edx
movl $0x1, %ecx
callq 0x113f0
jmp 0xd375
leaq -0x48(%rbp), %rdi
callq 0x10930
movq 0xb1c6b(%rip), %rdi     # 0xbeff0
movq 0xb1bd4(%rip), %rsi     # 0xbef60
callq 0x85f0
jmp 0xd3ad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x10930
jmp 0xdbc7
leaq -0x28(%rbp), %rdi
callq 0x113d0
movq %rax, %rsi
addq $0x20, %rsi
leaq -0x70(%rbp), %rdi
callq 0x110a0
leaq -0x70(%rbp), %rdi
callq 0x10e50
cmpq $0x0, %rax
jbe 0xdb9c
leaq -0x90(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x110a0
jmp 0xd3eb
leaq -0x90(%rbp), %rdi
callq 0x11500
movsd %xmm0, -0x2860(%rbp)
jmp 0xd401
leaq -0x70(%rbp), %rdi
callq 0x10e50
movsd -0x2860(%rbp), %xmm0
addq %rax, %rax
movq %rax, %xmm1
movaps 0x7b05f(%rip), %xmm2    # 0x88480
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x7b063(%rip), %xmm2    # 0x88490
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x2880(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x10930
movsd -0x2880(%rbp), %xmm0
movq -0x2838(%rbp), %rax
movsd %xmm0, -0x78(%rbp)
movsd -0x78(%rbp), %xmm0
movsd %xmm0, -0x2878(%rbp)
addq $0x258, %rax            # imm = 0x258
movq %rax, -0x2870(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x113d0
movq -0x2870(%rbp), %rdi
movq %rax, %rsi
callq 0x10db0
movq %rax, -0x2868(%rbp)
jmp 0xd4a3
movq -0x2868(%rbp), %rax
movsd -0x2878(%rbp), %xmm0
movsd %xmm0, (%rax)
leaq -0x1418(%rbp), %rdi
callq 0x111c0
jmp 0xd4c4
leaq -0x1418(%rbp), %rdi
callq 0x11260
movl %eax, -0x2884(%rbp)
jmp 0xd4d8
movl -0x2884(%rbp), %eax
movl %eax, %eax
movl %eax, %esi
leaq -0x27a0(%rbp), %rdi
callq 0x11280
jmp 0xd4f0
leaq -0x70(%rbp), %rdi
callq 0x10e50
movl %eax, %edx
decl %edx
leaq -0x27a8(%rbp), %rdi
xorl %esi, %esi
callq 0x112b0
jmp 0xd50d
leaq -0x27c0(%rbp), %rdi
callq 0x10800
leaq -0x27d8(%rbp), %rdi
callq 0x10800
movl $0x0, -0x27dc(%rbp)
movslq -0x27dc(%rbp), %rax
movq %rax, -0x2890(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x10e50
movq %rax, %rcx
movq -0x2890(%rbp), %rax
cmpq %rcx, %rax
jae 0xd64f
leaq -0x27a8(%rbp), %rdi
leaq -0x27a0(%rbp), %rsi
callq 0x112e0
movl %eax, -0x2894(%rbp)
jmp 0xd574
movl -0x2894(%rbp), %eax
movl %eax, -0x27e0(%rbp)
leaq -0x27a8(%rbp), %rdi
leaq -0x27a0(%rbp), %rsi
callq 0x112e0
movl %eax, -0x2898(%rbp)
jmp 0xd59b
movl -0x2898(%rbp), %eax
movl %eax, -0x27e4(%rbp)
movslq -0x27e0(%rbp), %rsi
leaq -0x70(%rbp), %rdi
callq 0x107e0
movq %rax, %rsi
leaq -0x27c0(%rbp), %rdi
callq 0x10f70
jmp 0xd5c8
movslq -0x27e4(%rbp), %rsi
leaq -0x70(%rbp), %rdi
callq 0x107e0
movq %rax, %rsi
leaq -0x27d8(%rbp), %rdi
callq 0x10f70
jmp 0xd5e9
jmp 0xd5eb
movl -0x27dc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x27dc(%rbp)
jmp 0xd52f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xdbb3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x10930
jmp 0xdbb3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xdb8e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xdb76
leaq -0x2808(%rbp), %rdi
leaq -0x27c0(%rbp), %rsi
callq 0x110a0
jmp 0xd664
leaq -0x2808(%rbp), %rdi
callq 0x11500
movsd %xmm0, -0x28a0(%rbp)
jmp 0xd67a
leaq -0x70(%rbp), %rdi
callq 0x10e50
movsd -0x28a0(%rbp), %xmm0
addq %rax, %rax
movq %rax, %xmm1
movaps 0x7ade6(%rip), %xmm2    # 0x88480
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x7adea(%rip), %xmm2    # 0x88490
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x28a8(%rbp)
leaq -0x2808(%rbp), %rdi
callq 0x10930
movsd -0x28a8(%rbp), %xmm0
movsd %xmm0, -0x27f0(%rbp)
leaq -0x2828(%rbp), %rdi
leaq -0x27d8(%rbp), %rsi
callq 0x110a0
jmp 0xd6f2
leaq -0x2828(%rbp), %rdi
callq 0x11500
movsd %xmm0, -0x28b0(%rbp)
jmp 0xd708
leaq -0x70(%rbp), %rdi
callq 0x10e50
movsd -0x28b0(%rbp), %xmm0
addq %rax, %rax
movq %rax, %xmm1
movaps 0x7ad58(%rip), %xmm2    # 0x88480
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x7ad5c(%rip), %xmm2    # 0x88490
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x28d0(%rbp)
leaq -0x2828(%rbp), %rdi
callq 0x10930
movsd -0x28d0(%rbp), %xmm0
movq -0x2838(%rbp), %rax
movsd %xmm0, -0x2810(%rbp)
movsd -0x27f0(%rbp), %xmm0
movsd %xmm0, -0x28c8(%rbp)
addq $0x4c8, %rax            # imm = 0x4C8
movq %rax, -0x28c0(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x113d0
movq -0x28c0(%rbp), %rdi
movq %rax, %rsi
callq 0x10db0
movq %rax, -0x28b8(%rbp)
jmp 0xd7b0
movq -0x2838(%rbp), %rax
movq -0x28b8(%rbp), %rcx
movsd -0x28c8(%rbp), %xmm0
movsd %xmm0, (%rcx)
movsd -0x2810(%rbp), %xmm0
movsd %xmm0, -0x28e8(%rbp)
addq $0x4f8, %rax            # imm = 0x4F8
movq %rax, -0x28e0(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x113d0
movq -0x28e0(%rbp), %rdi
movq %rax, %rsi
callq 0x10db0
movq %rax, -0x28d8(%rbp)
jmp 0xd808
movq -0x2838(%rbp), %rax
movq -0x28d8(%rbp), %rcx
movsd -0x28e8(%rbp), %xmm0
movsd %xmm0, (%rcx)
cmpl $0x0, 0x4(%rax)
jne 0xda20
movq -0x2838(%rbp), %rax
movsd -0x78(%rbp), %xmm0
movsd %xmm0, -0x2900(%rbp)
addq $0x290, %rax            # imm = 0x290
movq %rax, -0x28f8(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x113d0
movq -0x28f8(%rbp), %rdi
movq %rax, %rsi
callq 0x10db0
movq %rax, -0x28f0(%rbp)
jmp 0xd86e
movq -0x2838(%rbp), %rax
movq -0x28f0(%rbp), %rcx
movsd -0x2900(%rbp), %xmm0
movsd %xmm0, (%rcx)
movsd -0x27f0(%rbp), %xmm0
movsd %xmm0, -0x2918(%rbp)
addq $0x528, %rax            # imm = 0x528
movq %rax, -0x2910(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x113d0
movq -0x2910(%rbp), %rdi
movq %rax, %rsi
callq 0x10db0
movq %rax, -0x2908(%rbp)
jmp 0xd8c6
movq -0x2838(%rbp), %rax
movq -0x2908(%rbp), %rcx
movsd -0x2918(%rbp), %xmm0
movsd %xmm0, (%rcx)
movsd -0x2810(%rbp), %xmm0
movsd %xmm0, -0x2930(%rbp)
addq $0x558, %rax            # imm = 0x558
movq %rax, -0x2928(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x113d0
movq -0x2928(%rbp), %rdi
movq %rax, %rsi
callq 0x10db0
movq %rax, -0x2920(%rbp)
jmp 0xd91e
movq -0x2920(%rbp), %rax
movsd -0x2930(%rbp), %xmm0
movsd %xmm0, (%rax)
jmp 0xdb5c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x2808(%rbp), %rdi
callq 0x10930
jmp 0xdb76
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x2828(%rbp), %rdi
callq 0x10930
jmp 0xdb76
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0xdb76
movq -0x50(%rbp), %rdi
callq 0x8220
movq %rax, -0x2830(%rbp)
movq 0xb164d(%rip), %rdi     # 0xbeff0
leaq 0x7ad13(%rip), %rsi     # 0x886bd
callq 0x8590
movq %rax, -0x2938(%rbp)
jmp 0xd9b8
leaq -0x28(%rbp), %rdi
callq 0x113d0
movq -0x2938(%rbp), %rdi
movq %rax, %rsi
callq 0x8520
movq %rax, -0x2940(%rbp)
jmp 0xd9d9
movq -0x2940(%rbp), %rdi
movq 0xb1579(%rip), %rsi     # 0xbef60
callq 0x85f0
jmp 0xd9ee
callq 0x8950
jmp 0xd9f5
jmp 0xd9f7
leaq -0x27d8(%rbp), %rdi
callq 0x10930
leaq -0x27c0(%rbp), %rdi
callq 0x10930
leaq -0x1418(%rbp), %rdi
callq 0x11310
jmp 0xdb9c
movq -0x2838(%rbp), %rax
cmpl $0x1, 0x4(%rax)
jne 0xdb5a
movq -0x2838(%rbp), %rax
movsd -0x78(%rbp), %xmm1
movsd 0x7aa63(%rip), %xmm0    # 0x884a8
subsd %xmm1, %xmm0
movsd %xmm0, -0x2958(%rbp)
addq $0x290, %rax            # imm = 0x290
movq %rax, -0x2950(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x113d0
movq -0x2950(%rbp), %rdi
movq %rax, %rsi
callq 0x10db0
movq %rax, -0x2948(%rbp)
jmp 0xda7f
movq -0x2838(%rbp), %rax
movq -0x2948(%rbp), %rcx
movsd -0x2958(%rbp), %xmm0
movsd %xmm0, (%rcx)
movsd -0x27f0(%rbp), %xmm1
movsd 0x7a9ff(%rip), %xmm0    # 0x884a8
subsd %xmm1, %xmm0
movsd %xmm0, -0x2970(%rbp)
addq $0x528, %rax            # imm = 0x528
movq %rax, -0x2968(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x113d0
movq -0x2968(%rbp), %rdi
movq %rax, %rsi
callq 0x10db0
movq %rax, -0x2960(%rbp)
jmp 0xdae3
movq -0x2838(%rbp), %rax
movq -0x2960(%rbp), %rcx
movsd -0x2970(%rbp), %xmm0
movsd %xmm0, (%rcx)
movsd -0x2810(%rbp), %xmm1
movsd 0x7a99b(%rip), %xmm0    # 0x884a8
subsd %xmm1, %xmm0
movsd %xmm0, -0x2988(%rbp)
addq $0x558, %rax            # imm = 0x558
movq %rax, -0x2980(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x113d0
movq -0x2980(%rbp), %rdi
movq %rax, %rsi
callq 0x10db0
movq %rax, -0x2978(%rbp)
jmp 0xdb47
movq -0x2978(%rbp), %rax
movsd -0x2988(%rbp), %xmm0
movsd %xmm0, (%rax)
jmp 0xdb5c
jmp 0xd9f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
callq 0x8950
jmp 0xdb74
jmp 0xdb76
leaq -0x27d8(%rbp), %rdi
callq 0x10930
leaq -0x27c0(%rbp), %rdi
callq 0x10930
leaq -0x1418(%rbp), %rdi
callq 0x11310
jmp 0xdbb3
leaq -0x70(%rbp), %rdi
callq 0x10930
leaq -0x28(%rbp), %rdi
callq 0x11570
jmp 0xd299
leaq -0x70(%rbp), %rdi
callq 0x10930
jmp 0xdbc7
addq $0x2990, %rsp           # imm = 0x2990
popq %rbp
retq
movq -0x50(%rbp), %rdi
callq 0x8a50
movq %rax, %rdi
callq 0x9d40
nopl (%rax,%rax)