// File: /workspace/github_cpp_makefile_star2_O2/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 $0xc8, %rsp
movq %rsi, %r15
movq %rdi, %rbx
callq 0x28746
leaq 0x70(%rbx), %rdi
movq 0x8(%r15), %rsi
subq (%r15), %rsi
sarq $0x5, %rsi
addq $-0x9, %rsi
leaq 0x40(%rsp), %rdx
andl $0x0, (%rdx)
movq %rdi, 0x70(%rsp)
movq %rbx, 0x20(%rsp)
callq 0x44dfe
leaq 0xb8(%rbx), %rdi
movq 0x8(%r15), %rsi
subq (%r15), %rsi
sarq $0x4, %rsi
addq $-0x12, %rsi
leaq 0x40(%rsp), %rdx
andl $0x0, (%rdx)
callq 0x44dfe
movl $0x100, %esi            # imm = 0x100
addq (%r15), %rsi
leaq 0x40(%rsp), %rdi
pushq $0x3a
popq %rdx
callq 0x40349
movq 0x40(%rsp), %rdi
movq 0x48(%rsp), %rsi
leaq 0x5e3f0(%rip), %rdx     # 0x9f202
callq 0x458a4
movq %rax, 0x68(%rsp)
movq 0x40(%rsp), %r14
movq 0x48(%rsp), %rsi
leaq 0x5e3d8(%rip), %rdx     # 0x9f205
movq %r14, %rdi
movq %rsi, 0xa0(%rsp)
callq 0x458a4
movq %rax, %rcx
movq 0x68(%rsp), %rax
subq %r14, %rax
shrq $0x5, %rax
cltq
movq %rax, 0x60(%rsp)
movq 0x40(%rsp), %rax
movq %rcx, 0x98(%rsp)
subq %rax, %rcx
shrq $0x5, %rcx
movslq %ecx, %rax
movq %rax, 0x58(%rsp)
movq (%r15), %rsi
movq 0x120(%rsi), %rax
cmpb $0x7c, 0x1(%rax)
jne 0x40e83
movb $0x1, 0x68(%rbx)
movq 0x48(%rsp), %rax
movq %rax, 0x90(%rsp)
leaq 0xd0(%rbx), %rax
movq %rax, 0x88(%rsp)
leaq 0x88(%rbx), %rax
movq %rax, 0x80(%rsp)
leaq 0xa0(%rbx), %rax
movq %rax, 0x78(%rsp)
movl $0x120, %ebp            # imm = 0x120
xorl %r14d, %r14d
shlq $0x5, 0x58(%rsp)
shlq $0x5, 0x60(%rsp)
xorl %r12d, %r12d
leaq 0x9(%r14), %rax
movq 0x8(%r15), %rcx
subq %rsi, %rcx
sarq $0x5, %rcx
cmpq %rcx, %rax
je 0x41084
movq 0x120(%rsi,%r12,8), %rax
movb (%rax), %bl
movb 0x2(%rax), %r13b
cmpb $0x2e, %bl
sete %al
cmpb $0x2e, %r13b
sete %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0x40f2a
movq 0x20(%rsp), %rax
movb $0x1, 0xf8(%rax)
movq 0x88(%rsp), %rdi
movq %r14, %rsi
callq 0x439c0
orq %rdx, (%rax)
movq 0x20(%rsp), %rax
cmpb $0x0, 0x68(%rax)
je 0x40f41
cmpb $0x31, %bl
movq 0x20(%rsp), %rbx
je 0x40f80
jmp 0x40f95
movl %ebx, %eax
xorb $0x30, %al
movl %r13d, %ecx
xorb $0x31, %cl
orb %al, %cl
je 0x40f5d
movl %ebx, %eax
xorb $0x31, %al
movl %r13d, %ecx
xorb $0x30, %cl
orb %al, %cl
jne 0x40f35
callq 0x8160
cvtsi2sd %eax, %xmm0
divsd 0x511b2(%rip), %xmm0    # 0x92120
movb $0x30, %r13b
ucomisd 0x56687(%rip), %xmm0    # 0x97600
movq 0x20(%rsp), %rbx
ja 0x40f9b
incl (%rbx)
movq 0x70(%rbx), %rax
incl (%rax,%r12)
movq 0xb8(%rbx), %rax
incl (%rax,%r12,2)
cmpb $0x31, %r13b
jne 0x40fb1
incl (%rbx)
movq 0x70(%rbx), %rax
incl (%rax,%r12)
movq 0xb8(%rbx), %rax
incl 0x4(%rax,%r12,2)
movq (%r15), %rsi
addq %rbp, %rsi
leaq 0x8(%rsp), %rdi
pushq $0x3a
popq %rdx
callq 0x40349
movq 0xa0(%rsp), %rax
cmpq %rax, 0x68(%rsp)
je 0x4101f
movq (%r15), %rax
movq 0x120(%rax,%r12,8), %rax
cmpb $0x2e, (%rax)
je 0x4101f
movq 0x8(%rsp), %rax
movq 0x60(%rsp), %rcx
movq (%rax,%rcx), %r13
movq %r13, %rdi
callq 0x86f0
cmpl 0x4(%rbx), %eax
jge 0x41001
movl %eax, 0x4(%rbx)
movq %r13, %rdi
callq 0x86f0
movl %eax, 0x28(%rsp)
movq 0x80(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x2c80c
movq 0x90(%rsp), %rax
cmpq %rax, 0x98(%rsp)
je 0x41067
movq (%r15), %rax
movq 0x120(%rax,%r12,8), %rax
cmpb $0x2e, (%rax)
je 0x41067
movq 0x8(%rsp), %rax
movq 0x58(%rsp), %rcx
movq (%rax,%rcx), %rdi
callq 0x86f0
movl %eax, 0x28(%rsp)
movq 0x78(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x2c80c
leaq 0x8(%rsp), %rdi
callq 0x28a08
movq (%r15), %rsi
addq $0x4, %r12
addq $0x20, %rbp
incq %r14
jmp 0x40ed1
addq $0xe0, %rsi
leaq 0x8(%rsp), %rdi
pushq $0x3b
popq %rdx
callq 0x40349
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
leaq -0xb92(%rip), %rdx      # 0x40517
callq 0x4598e
cmpq 0x10(%rsp), %rax
je 0x410f7
movq 0x8(%rsp), %rcx
subq %rcx, %rax
shlq $0x1b, %rax
sarq $0x1b, %rax
addq %rcx, %rax
leaq 0x28(%rsp), %rdi
pushq $0x3d
popq %rdx
movq %rax, %rsi
callq 0x40349
leaq 0x28(%rsp), %r14
movq 0x8(%r14), %rax
movq -0x20(%rax), %rdi
callq 0x86f0
movl %eax, 0x8(%rbx)
movq %r14, %rdi
callq 0x28a08
jmp 0x410fb
andl $0x0, 0x8(%rbx)
movq 0x40(%rsp), %rdi
movq 0x48(%rsp), %rsi
leaq -0xbad(%rip), %rdx      # 0x4055f
callq 0x4598e
cmpq 0x48(%rsp), %rax
jne 0x41179
subq 0x40(%rsp), %rax
shlq $0x1b, %rax
sarq $0x1b, %rax
addq 0x8(%rsp), %rax
leaq 0x28(%rsp), %rdi
pushq $0x3d
popq %rdx
movq %rax, %rsi
callq 0x40349
movq 0x30(%rsp), %rsi
addq $-0x20, %rsi
leaq 0xa8(%rsp), %rdi
callq 0x8600
leaq 0xa8(%rsp), %rdi
callq 0x402aa
movsd %xmm0, 0x50(%rbx)
leaq 0xa8(%rsp), %rdi
callq 0x8978
leaq 0x28(%rsp), %rdi
callq 0x28a08
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
leaq -0xc5b(%rip), %rdx      # 0x4052f
callq 0x4598e
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
cmpq %rsi, %rax
je 0x411d0
subq %rdi, %rax
shlq $0x1b, %rax
sarq $0x1b, %rax
addq %rdi, %rax
leaq 0x28(%rsp), %rdi
pushq $0x3d
popq %rdx
movq %rax, %rsi
callq 0x40349
movq 0x30(%rsp), %rsi
addq $-0x20, %rsi
leaq 0x10(%rbx), %rdi
callq 0x82a0
jmp 0x41218
leaq -0xc90(%rip), %rdx      # 0x40547
callq 0x4598e
cmpq 0x10(%rsp), %rax
je 0x41222
movq 0x8(%rsp), %rcx
subq %rcx, %rax
shlq $0x1b, %rax
sarq $0x1b, %rax
addq %rcx, %rax
leaq 0x28(%rsp), %rdi
pushq $0x3d
popq %rdx
movq %rax, %rsi
callq 0x40349
movq 0x30(%rsp), %rsi
addq $-0x20, %rsi
leaq 0x30(%rbx), %rdi
callq 0x82a0
leaq 0x28(%rsp), %rdi
callq 0x28a08
movq 0x70(%rsp), %rdi
callq 0x40577
movsd %xmm0, 0x58(%rbx)
leaq 0x8(%rsp), %rdi
callq 0x28a08
leaq 0x40(%rsp), %rdi
callq 0x28a08
movq %rbx, %rax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x41276
jmp 0x412a0
jmp 0x412a0
movq %rax, %r14
leaq 0xa8(%rsp), %rdi
callq 0x8978
jmp 0x41279
jmp 0x41276
jmp 0x412a0
movq %rax, %r14
leaq 0x28(%rsp), %rdi
callq 0x28a08
jmp 0x412a3
jmp 0x412a0
jmp 0x412a0
jmp 0x412a0
jmp 0x412a0
jmp 0x412a0
jmp 0x412b1
jmp 0x412b1
jmp 0x412b1
jmp 0x41299
jmp 0x41299
movq %rax, %r14
jmp 0x412be
jmp 0x412a0
movq %rax, %r14
leaq 0x8(%rsp), %rdi
callq 0x28a08
jmp 0x412b4
jmp 0x412b1
movq %rax, %r14
leaq 0x40(%rsp), %rdi
callq 0x28a08
movq 0x20(%rsp), %rdi
callq 0x289b4
movq %r14, %rdi
callq 0x8870