// File: /workspace/github_cpp_makefile_star2_O3/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)
movsd 0x7d8c4(%rip), %xmm0    # 0xcbd20
movupd %xmm0, 0x50(%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, 0x58(%rsp)
callq 0x56106
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 0x56106
movl $0x100, %esi            # imm = 0x100
addq (%r15), %rsi
leaq 0x30(%rsp), %rdi
movl $0x3a, %edx
callq 0x4d650
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rsi
leaq 0x81fe4(%rip), %rdx     # 0xd051e
callq 0x56e10
movq %rax, %r12
movq 0x30(%rsp), %r14
movq 0x38(%rsp), %rsi
leaq 0x81fce(%rip), %rdx     # 0xd0521
movq %r14, %rdi
movq %rsi, 0x90(%rsp)
callq 0x56e10
movq %rax, 0x50(%rsp)
movq (%r15), %rsi
movq 0x120(%rsi), %rax
cmpb $0x7c, 0x1(%rax)
jne 0x4e57c
movb $0x1, 0x68(%rbx)
movq 0x8(%r15), %rax
subq %rsi, %rax
cmpq $0x120, %rax            # imm = 0x120
je 0x4e819
movq %r12, %rax
subq %r14, %rax
movq 0x30(%rsp), %rcx
movq 0x50(%rsp), %rdx
subq %rcx, %rdx
shrq $0x5, %rax
shrq $0x5, %rdx
cltq
movq 0x38(%rsp), %rcx
movq %rcx, 0x88(%rsp)
movslq %edx, %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
leaq 0x88(%rbx), %rdi
movq %rdi, 0x68(%rsp)
leaq 0xa0(%rbx), %rdi
movq %rdi, 0x60(%rsp)
movl $0x9, %r13d
movl $0x120, %ebp            # imm = 0x120
xorl %r14d, %r14d
addq $0x3f, %rdx
movq %rdx, 0x80(%rsp)
shlq $0x5, %rcx
movq %rcx, 0x70(%rsp)
shlq $0x5, %rax
movq %rax, 0x78(%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 0x4e682
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 0x80(%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)
je 0x4e68f
cmpb $0x31, %dl
je 0x4e6cf
jmp 0x4e6e4
movl %edx, %ecx
xorb $0x30, %cl
movl %eax, %esi
xorb $0x31, %sil
orb %cl, %sil
je 0x4e6af
movl %edx, %ecx
xorb $0x31, %cl
movl %eax, %esi
xorb $0x30, %sil
orb %cl, %sil
jne 0x4e688
callq 0x8140
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd 0x81c5d(%rip), %xmm0    # 0xd0320
movb $0x30, %al
ucomisd 0x7e053(%rip), %xmm0    # 0xcc720
ja 0x4e6e8
incl (%rbx)
movq 0x70(%rbx), %rcx
incl (%rcx,%r14)
movq 0xb8(%rbx), %rcx
incl (%rcx,%r14,2)
cmpb $0x31, %al
jne 0x4e6fe
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 0x4d650
cmpq 0x90(%rsp), %r12
je 0x4e78c
movq (%r15), %rax
movq 0x120(%rax,%r14,8), %rax
cmpb $0x2e, (%rax)
je 0x4e78c
movq (%rsp), %rax
movq 0x78(%rsp), %rcx
movq (%rax,%rcx), %r12
movq %r12, %rdi
callq 0x86e0
cmpl 0x4(%rbx), %eax
jge 0x4e748
movl %eax, 0x4(%rbx)
movq %r12, %rdi
callq 0x86e0
movl %eax, 0x18(%rsp)
movq 0x90(%rbx), %rsi
cmpq 0x98(%rbx), %rsi
je 0x4e778
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x90(%rbx)
movq 0x48(%rsp), %r12
jmp 0x4e78c
movq 0x68(%rsp), %rdi
leaq 0x18(%rsp), %rdx
callq 0x33074
movq 0x48(%rsp), %r12
movq 0x88(%rsp), %rax
cmpq %rax, 0x50(%rsp)
je 0x4e7ef
movq (%r15), %rax
movq 0x120(%rax,%r14,8), %rax
cmpb $0x2e, (%rax)
je 0x4e7ef
movq (%rsp), %rax
movq 0x70(%rsp), %rcx
movq (%rax,%rcx), %rdi
callq 0x86e0
movl %eax, 0x18(%rsp)
movq 0xa8(%rbx), %rsi
cmpq 0xb0(%rbx), %rsi
je 0x4e7e0
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0xa8(%rbx)
jmp 0x4e7ef
movq 0x60(%rsp), %rdi
leaq 0x18(%rsp), %rdx
callq 0x33074
movq %rsp, %rdi
callq 0x2e784
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 0x4e60f
addq $0xe0, %rsi
movq %rsp, %rdi
movl $0x3b, %edx
callq 0x4d650
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
leaq -0xfb4(%rip), %rdx      # 0x4d889
callq 0x56f01
cmpq 0x8(%rsp), %rax
je 0x4e88c
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 0x4d650
leaq 0x18(%rsp), %r14
movq 0x8(%r14), %rax
movq -0x20(%rax), %rdi
callq 0x86e0
movl %eax, 0x8(%rbx)
movq %r14, %rdi
callq 0x2e784
jmp 0x4e893
movl $0x0, 0x8(%rbx)
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rsi
leaq -0xfc4(%rip), %rdx      # 0x4d8e0
callq 0x56f01
cmpq 0x38(%rsp), %rax
jne 0x4e939
subq 0x30(%rsp), %rax
shlq $0x1b, %rax
sarq $0x1b, %rax
addq (%rsp), %rax
leaq 0x18(%rsp), %rdi
movq %rax, %rsi
movl $0x3d, %edx
callq 0x4d650
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 0x2ba06
leaq 0x98(%rsp), %rdi
callq 0x4d578
movsd %xmm0, 0x50(%rbx)
movq 0x98(%rsp), %rdi
cmpq %r15, %rdi
je 0x4e92f
movq 0xa8(%rsp), %rsi
incq %rsi
callq 0x8480
leaq 0x18(%rsp), %rdi
callq 0x2e784
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
leaq -0x10a3(%rip), %rdx     # 0x4d8a6
callq 0x56f01
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
cmpq %rsi, %rax
je 0x4e990
subq %rdi, %rax
shlq $0x1b, %rax
sarq $0x1b, %rax
addq %rdi, %rax
leaq 0x18(%rsp), %rdi
movq %rax, %rsi
movl $0x3d, %edx
callq 0x4d650
leaq 0x10(%rbx), %rdi
movq 0x20(%rsp), %rsi
addq $-0x20, %rsi
callq 0x8270
jmp 0x4e9d9
leaq -0x10d4(%rip), %rdx     # 0x4d8c3
callq 0x56f01
cmpq 0x8(%rsp), %rax
je 0x4e9e3
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 0x4d650
leaq 0x30(%rbx), %rdi
movq 0x20(%rsp), %rsi
addq $-0x20, %rsi
callq 0x8270
leaq 0x18(%rsp), %rdi
callq 0x2e784
movq 0x58(%rsp), %rdi
callq 0x4d8fd
movsd %xmm0, 0x58(%rbx)
movq %rsp, %rdi
callq 0x2e784
leaq 0x30(%rsp), %rdi
callq 0x2e784
movq %rbx, %rax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x4ea45
jmp 0x4ea6f
jmp 0x4ea6f
movq %rax, %r14
movq 0x98(%rsp), %rdi
cmpq %r15, %rdi
je 0x4ea48
movq 0xa8(%rsp), %rsi
incq %rsi
callq 0x8480
jmp 0x4ea48
jmp 0x4ea45
jmp 0x4ea6f
movq %rax, %r14
leaq 0x18(%rsp), %rdi
callq 0x2e784
jmp 0x4ea72
jmp 0x4ea6f
jmp 0x4ea6f
jmp 0x4ea6f
jmp 0x4ea6f
jmp 0x4ea6f
jmp 0x4ea7c
jmp 0x4ea7c
jmp 0x4ea7c
jmp 0x4ea68
jmp 0x4ea68
movq %rax, %r14
jmp 0x4ea89
jmp 0x4ea6f
movq %rax, %r14
movq %rsp, %rdi
callq 0x2e784
jmp 0x4ea7f
movq %rax, %r14
leaq 0x30(%rsp), %rdi
callq 0x2e784
movq %rbx, %rdi
callq 0x2e6d0
movq %r14, %rdi
callq 0x8840