// File: /workspace/github_cpp_makefile_star2_O1/millanek[P]evo/process_vcf_utils.cpp
// Function: getThisVariantCounts(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&)
Counts getThisVariantCounts(const std::vector<std::string>& fields) {
    Counts thisVariantCounts;
    bool hasGQ = false; bool hasDP = false;
    thisVariantCounts.individualsWithVariant.assign((fields.size()-NUM_NON_GENOTYPE_COLUMNS),0);
    thisVariantCounts.haplotypesWithVariant.assign((fields.size()-NUM_NON_GENOTYPE_COLUMNS)*2,0);
    //std::cerr << "Fields: " << (fields.size()-NUM_NON_GENOTYPE_COLUMNS) << std::endl;
    // Find the position of DP (per sample read depth) in the genotypeData vector below
    std::vector<std::string> format = split(fields[8], ':');
    std::vector<std::string>::iterator DPit; int DPi = std::numeric_limits<int>::min();
    DPit = find (format.begin(), format.end(), "DP");
    if (DPit == format.end()) {
        // std::cerr << "This variant hasn't got associated per-sample DP info" << std::endl;
    } else {
        DPi = (int)std::distance( format.begin(), DPit );
        hasDP = true;
    }
    // Find the position of GQ (genotype quality) in the genotypeData vector below
    std::vector<std::string>::iterator GQit; int GQi = std::numeric_limits<int>::min();
    GQit = find (format.begin(), format.end(), "GQ");
    if (GQit == format.end()) {
        // std::cerr << "This variant hasn't got associated per-sample GQ info" << std::endl;
    } else {
        GQi = (int)std::distance( format.begin(), GQit );
        hasGQ = true;
    }
    
    if (fields[NUM_NON_GENOTYPE_COLUMNS][1] == '|') { thisVariantCounts.bPhased = true; }
    
    for (std::vector<std::string>::size_type i = NUM_NON_GENOTYPE_COLUMNS; i != fields.size(); i++) {
        char v1 = fields[i][0]; char v2 = fields[i][2];
        if (v1 == '.' || v2 == '.') {
            thisVariantCounts.bAnyMissingGenotypes = true;
            thisVariantCounts.missingGenotypesPerIndividual[i- NUM_NON_GENOTYPE_COLUMNS] = true;
        }
        if (thisVariantCounts.bPhased == false) {
            if ((v1 == '0' && v2 == '1') || (v1 == '1' && v2 == '0')) {
            double r = ((double) rand() / (RAND_MAX));
            if (r > 0.5) {
                v1 = '0'; v2 = '1';
            } else {
                v1 = '1'; v2 = '0';
            }
            }
        }
        
        if (v1 == '1') {
            thisVariantCounts.overall++;
            thisVariantCounts.individualsWithVariant[i- NUM_NON_GENOTYPE_COLUMNS]++;
            thisVariantCounts.haplotypesWithVariant[2*(i-NUM_NON_GENOTYPE_COLUMNS)]++;
        }
        if (v2 == '1') {
            thisVariantCounts.overall++;
            thisVariantCounts.individualsWithVariant[i-NUM_NON_GENOTYPE_COLUMNS]++;
            thisVariantCounts.haplotypesWithVariant[2*(i-NUM_NON_GENOTYPE_COLUMNS)+1]++;
        }
            
        std::vector<std::string> genotypeData = split(fields[i], ':');
        
        // read depth at the variant site per individual
        if (hasDP && fields[i][0] != '.') {
            if (atoi(genotypeData[DPi].c_str()) < thisVariantCounts.minimumDepthInAnIndividual) {
                thisVariantCounts.minimumDepthInAnIndividual = atoi(genotypeData[DPi].c_str());
            }
            thisVariantCounts.depthPerIndividual.push_back(atoi(genotypeData[DPi].c_str()));
        }
        // genotype quality at the variant site per individual
        if (hasGQ && fields[i][0] != '.') {
            thisVariantCounts.genotypeQualitiesPerIndividual.push_back(atoi(genotypeData[GQi].c_str()));
        }
    }
    // Also get overall depth for this variant
    std::vector<std::string> info = split(fields[7], ';');
    std::vector<std::string>::iterator overallDPit; int overallDPi = std::numeric_limits<int>::min();
    overallDPit = find_if(info.begin(), info.end(), isDPinfo);
    if (overallDPit == info.end()) {
        // std::cerr << "This variant hasn't got associated overall DP info" << std::endl;
        thisVariantCounts.overallDepth = 0;
    } else {
        overallDPi = (int)std::distance( info.begin(), overallDPit );
        std::vector<std::string> overallDP = split(info[overallDPi], '=');
        thisVariantCounts.overallDepth = atoi((overallDP.back()).c_str());
    }
    
    // Find the position of SGB (Segregation based metric) in the genotypeData vector below
    std::vector<std::string>::iterator SGBit; int SGBi = std::numeric_limits<int>::min();
    SGBit = find_if(format.begin(), format.end(), isSGBinfo);
    if (SGBit != format.end()) {
        // std::cerr << "This variant hasn't got associated per-sample GQ info" << std::endl;
    } else {
        SGBi = (int)std::distance( format.begin(), SGBit );
        std::vector<std::string> overallSGB = split(info[SGBi], '=');
        thisVariantCounts.SGB = stringToDouble(overallSGB.back());
    }
    
    // And get FS (phred-scaled strand-bias p-val) for this variant
    std::vector<std::string>::iterator FSit; int FSi = std::numeric_limits<int>::min();
    FSit = find_if(info.begin(), info.end(), isFSinfo);
    if (FSit == info.end()) {  // Or at least MQSB: Mann-Whitney U test of Mapping Quality vs Strand Bias
        FSit = find_if(info.begin(), info.end(), isMQSBinfo);
        if (FSit != info.end()) {
            FSi = (int)std::distance( info.begin(), FSit );
            std::vector<std::string> overallFS = split(info[FSi], '=');
            thisVariantCounts.MQSBpval = overallFS.back();
        } else {
            // std::cerr << "This variant hasn't got associated FS (strand-bias) info" << std::endl;
        }
    } else {
        FSi = (int)std::distance( info.begin(), FSit );
        std::vector<std::string> overallFS = split(info[FSi], '=');
        thisVariantCounts.FSpval =  overallFS.back();
    }

    // And the inbreeding coefficient
    thisVariantCounts.inbreedingCoefficient = calculateInbreedingCoefficient(thisVariantCounts.individualsWithVariant);
    
    return thisVariantCounts;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %rsi, %r15
movq %rdi, %rbx
movabsq $0x7fffffff00000000, %rax # imm = 0x7FFFFFFF00000000
movq %rax, (%rdi)
xorl %eax, %eax
movl %eax, 0x8(%rdi)
leaq 0x20(%rdi), %rcx
movq %rcx, 0x10(%rdi)
movq %rax, 0x18(%rdi)
movb %al, 0x20(%rdi)
leaq 0x40(%rdi), %rcx
movq %rcx, 0x30(%rdi)
movq %rax, 0x38(%rdi)
movb %al, 0x40(%rdi)
movabsq $0x7fefffffffffffff, %rcx # imm = 0x7FEFFFFFFFFFFFFF
movq %rcx, 0x50(%rdi)
movq %rax, 0x58(%rdi)
movabsq $0x3ff0000000000000, %rcx # imm = 0x3FF0000000000000
movq %rcx, 0x60(%rdi)
movb %al, 0x68(%rdi)
leaq 0x70(%rdi), %rdi
movq %rax, 0xe0(%rbx)
movl %eax, 0xe8(%rbx)
movq %rax, 0xf0(%rbx)
movw $0x0, 0xf8(%rbx)
xorpd %xmm0, %xmm0
movupd %xmm0, 0x70(%rbx)
movupd %xmm0, 0x80(%rbx)
movupd %xmm0, 0x90(%rbx)
movupd %xmm0, 0xa0(%rbx)
movupd %xmm0, 0xb0(%rbx)
movupd %xmm0, 0xc0(%rbx)
movupd %xmm0, 0xcc(%rbx)
movq 0x8(%rsi), %rsi
subq (%r15), %rsi
sarq $0x5, %rsi
addq $-0x9, %rsi
leaq 0x30(%rsp), %rdx
movl %eax, (%rdx)
movq %rdi, 0x60(%rsp)
callq 0x561e6
leaq 0xb8(%rbx), %rdi
movq 0x8(%r15), %rsi
subq (%r15), %rsi
sarq $0x4, %rsi
addq $-0x12, %rsi
leaq 0x30(%rsp), %rdx
movl $0x0, (%rdx)
callq 0x561e6
movl $0x100, %esi            # imm = 0x100
addq (%r15), %rsi
leaq 0x30(%rsp), %rdi
movl $0x3a, %edx
callq 0x50624
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rsi
leaq 0x85a4d(%rip), %rdx     # 0xd6ff2
callq 0x56c2c
movq %rax, %r12
movq 0x30(%rsp), %r14
movq 0x38(%rsp), %rsi
leaq 0x85a37(%rip), %rdx     # 0xd6ff5
movq %r14, %rdi
movq %rsi, 0x58(%rsp)
callq 0x56c2c
movq %rax, 0x50(%rsp)
movq (%r15), %rax
movq 0x120(%rax), %rax
cmpb $0x7c, 0x1(%rax)
jne 0x515e4
movb $0x1, 0x68(%rbx)
movq (%r15), %rsi
movq 0x8(%r15), %rax
subq %rsi, %rax
cmpq $0x120, %rax            # imm = 0x120
je 0x518a5
movq %r12, %rax
subq %r14, %rax
movq 0x30(%rsp), %rcx
movq 0x50(%rsp), %rdi
movq %rdi, %rdx
subq %rcx, %rdx
shrq $0x5, %rax
shrq $0x5, %rdx
movslq %eax, %rcx
movq 0x38(%rsp), %r8
movslq %edx, %rdx
cmpq 0x58(%rsp), %r12
movq $-0x80000000, %rax      # imm = 0x80000000
cmoveq %rax, %rcx
leaq 0x88(%rbx), %r9
movq %r9, 0x70(%rsp)
movq %r8, 0x90(%rsp)
cmpq %r8, %rdi
cmoveq %rax, %rdx
movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000
leaq 0xa0(%rbx), %rdi
movq %rdi, 0x68(%rsp)
movl $0x9, %r13d
movl $0x120, %ebp            # imm = 0x120
xorl %r14d, %r14d
addq $0x3f, %rax
movq %rax, 0x88(%rsp)
shlq $0x5, %rdx
movq %rdx, 0x78(%rsp)
shlq $0x5, %rcx
movq %rcx, 0x80(%rsp)
movq %r12, 0x48(%rsp)
movq 0x120(%rsi,%r14,8), %rax
movb (%rax), %dl
movb 0x2(%rax), %al
cmpb $0x2e, %dl
sete %cl
cmpb $0x2e, %al
sete %sil
orb %cl, %sil
cmpb $0x1, %sil
jne 0x5170b
movb $0x1, 0xf8(%rbx)
leaq -0x9(%r13), %rcx
leaq 0x36(%r13), %rsi
testq %rcx, %rcx
cmovnsq %rcx, %rsi
sarq $0x6, %rsi
shlq $0x3, %rsi
addq 0xd0(%rbx), %rsi
movq %rcx, %rdi
andq 0x88(%rsp), %rdi
xorl %r8d, %r8d
movabsq $-0x8000000000000000, %r9 # imm = 0x8000000000000000
cmpq %r9, %rdi
setbe %r8b
movl $0x1, %edi
shlq %cl, %rdi
orq %rdi, -0x8(%rsi,%r8,8)
cmpb $0x0, 0x68(%rbx)
jne 0x51756
movl %edx, %ecx
xorb $0x30, %cl
movl %eax, %esi
xorb $0x31, %sil
orb %cl, %sil
je 0x51731
movl %edx, %ecx
xorb $0x31, %cl
movl %eax, %esi
xorb $0x30, %sil
orb %cl, %sil
jne 0x51756
callq 0x8140
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd 0x789c3(%rip), %xmm0    # 0xca108
ucomisd 0x7dd03(%rip), %xmm0    # 0xcf450
seta %dl
leal 0x30(%rdx), %eax
xorb $0x31, %dl
cmpb $0x31, %dl
jne 0x51770
incl (%rbx)
movq 0x70(%rbx), %rcx
incl (%rcx,%r14)
movq 0xb8(%rbx), %rcx
incl (%rcx,%r14,2)
cmpb $0x31, %al
jne 0x5178a
incl (%rbx)
movq 0x70(%rbx), %rax
incl (%rax,%r14)
movq 0xb8(%rbx), %rax
incl 0x4(%rax,%r14,2)
movq (%r15), %rsi
addq %rbp, %rsi
movq %rsp, %rdi
movl $0x3a, %edx
callq 0x50624
cmpq 0x58(%rsp), %r12
je 0x51818
movq (%r15), %rax
movq 0x120(%rax,%r14,8), %rax
cmpb $0x2e, (%rax)
je 0x51818
movq (%rsp), %rax
movq 0x80(%rsp), %rcx
movq (%rax,%rcx), %r12
movq %r12, %rdi
callq 0x86e0
cmpl 0x4(%rbx), %eax
jge 0x517d4
movl %eax, 0x4(%rbx)
movq %r12, %rdi
callq 0x86e0
movl %eax, 0x18(%rsp)
movq 0x90(%rbx), %rsi
cmpq 0x98(%rbx), %rsi
je 0x51804
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x90(%rbx)
movq 0x48(%rsp), %r12
jmp 0x51818
movq 0x70(%rsp), %rdi
leaq 0x18(%rsp), %rdx
callq 0x35b1e
movq 0x48(%rsp), %r12
movq 0x90(%rsp), %rax
cmpq %rax, 0x50(%rsp)
je 0x5187b
movq (%r15), %rax
movq 0x120(%rax,%r14,8), %rax
cmpb $0x2e, (%rax)
je 0x5187b
movq (%rsp), %rax
movq 0x78(%rsp), %rcx
movq (%rax,%rcx), %rdi
callq 0x86e0
movl %eax, 0x18(%rsp)
movq 0xa8(%rbx), %rsi
cmpq 0xb0(%rbx), %rsi
je 0x5186c
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0xa8(%rbx)
jmp 0x5187b
movq 0x68(%rsp), %rdi
leaq 0x18(%rsp), %rdx
callq 0x35b1e
movq %rsp, %rdi
callq 0x3123c
incq %r13
movq (%r15), %rsi
movq 0x8(%r15), %rax
subq %rsi, %rax
sarq $0x5, %rax
addq $0x4, %r14
addq $0x20, %rbp
cmpq %rax, %r13
jne 0x51698
addq $0xe0, %rsi
movq %rsp, %rdi
movl $0x3b, %edx
callq 0x50624
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
leaq -0x106c(%rip), %rdx     # 0x5085d
callq 0x56d15
cmpq 0x8(%rsp), %rax
je 0x51918
movq (%rsp), %rcx
subq %rcx, %rax
shlq $0x1b, %rax
sarq $0x1b, %rax
addq %rcx, %rax
leaq 0x18(%rsp), %rdi
movq %rax, %rsi
movl $0x3d, %edx
callq 0x50624
leaq 0x18(%rsp), %r14
movq 0x8(%r14), %rax
movq -0x20(%rax), %rdi
callq 0x86e0
movl %eax, 0x8(%rbx)
movq %r14, %rdi
callq 0x3123c
jmp 0x5191f
movl $0x0, 0x8(%rbx)
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rsi
leaq -0x107c(%rip), %rdx     # 0x508b4
callq 0x56d15
cmpq 0x38(%rsp), %rax
jne 0x519c5
subq 0x30(%rsp), %rax
shlq $0x1b, %rax
sarq $0x1b, %rax
addq (%rsp), %rax
leaq 0x18(%rsp), %rdi
movq %rax, %rsi
movl $0x3d, %edx
callq 0x50624
movq 0x20(%rsp), %rax
leaq 0xa8(%rsp), %r15
movq %r15, -0x10(%r15)
movq -0x20(%rax), %rsi
movq -0x18(%rax), %rdx
addq %rsi, %rdx
leaq 0x98(%rsp), %rdi
callq 0x2e45c
leaq 0x98(%rsp), %rdi
callq 0x5054c
movsd %xmm0, 0x50(%rbx)
movq 0x98(%rsp), %rdi
cmpq %r15, %rdi
je 0x519bb
movq 0xa8(%rsp), %rsi
incq %rsi
callq 0x8480
leaq 0x18(%rsp), %rdi
callq 0x3123c
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
leaq -0x115b(%rip), %rdx     # 0x5087a
callq 0x56d15
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
cmpq %rsi, %rax
je 0x51a1c
subq %rdi, %rax
shlq $0x1b, %rax
sarq $0x1b, %rax
addq %rdi, %rax
leaq 0x18(%rsp), %rdi
movq %rax, %rsi
movl $0x3d, %edx
callq 0x50624
leaq 0x10(%rbx), %rdi
movq 0x20(%rsp), %rsi
addq $-0x20, %rsi
callq 0x8270
jmp 0x51a65
leaq -0x118c(%rip), %rdx     # 0x50897
callq 0x56d15
cmpq 0x8(%rsp), %rax
je 0x51a6f
movq (%rsp), %rcx
subq %rcx, %rax
shlq $0x1b, %rax
sarq $0x1b, %rax
addq %rcx, %rax
leaq 0x18(%rsp), %rdi
movq %rax, %rsi
movl $0x3d, %edx
callq 0x50624
leaq 0x30(%rbx), %rdi
movq 0x20(%rsp), %rsi
addq $-0x20, %rsi
callq 0x8270
leaq 0x18(%rsp), %rdi
callq 0x3123c
movq 0x60(%rsp), %rdi
callq 0x508d1
movsd %xmm0, 0x58(%rbx)
movq %rsp, %rdi
callq 0x3123c
leaq 0x30(%rsp), %rdi
callq 0x3123c
movq %rbx, %rax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x51ad1
jmp 0x51afb
jmp 0x51afb
movq %rax, %r14
movq 0x98(%rsp), %rdi
cmpq %r15, %rdi
je 0x51ad4
movq 0xa8(%rsp), %rsi
incq %rsi
callq 0x8480
jmp 0x51ad4
jmp 0x51ad1
jmp 0x51afb
movq %rax, %r14
leaq 0x18(%rsp), %rdi
callq 0x3123c
jmp 0x51afe
jmp 0x51afb
jmp 0x51afb
jmp 0x51afb
jmp 0x51afb
jmp 0x51afb
jmp 0x51b08
jmp 0x51b08
jmp 0x51b08
jmp 0x51af4
jmp 0x51af4
movq %rax, %r14
jmp 0x51b15
jmp 0x51afb
movq %rax, %r14
movq %rsp, %rdi
callq 0x3123c
jmp 0x51b0b
movq %rax, %r14
leaq 0x30(%rsp), %rdi
callq 0x3123c
movq %rbx, %rdi
callq 0x31188
movq %r14, %rdi
callq 0x8840