// File: /workspace/github_cpp_makefile_star2_O2/millanek[P]evo/process_vcf_testing.cpp
// Function: testMain(int, char**)
int testMain(int argc, char** argv) {
    parseTestOptions(argc, argv);
    std::ios_base::openmode mode = std::ios_base::in;
    string fileName = opt::vcfFile;
    string fileRoot = stripExtension(fileName);
    std::vector<int> depthsHetFailed;
    std::vector<int> depthsHetPassed;
    std::vector<int> numVariantsPerHetCount;
    std::vector<std::vector<int> > num_indiv_het_vs_depth;
    
    
    std::cerr << "Filtering variants from: " << fileName << std::endl;
    std::cerr << "Maximum read depth (overall) set to: " << opt::max_overall_depth << std::endl;
    std::cerr << "Minimum copies for a variant (e.g. 1 for allowing singletons): " << opt::min_copies << std::endl;
    std::cerr << "Minimum read depth at the variant position: " << opt::min_depth_in_any_individual << std::endl;
    std::cerr << "Filter out sites where more than " << opt::max_het_indiv << " individuals are heterozygous"  << std::endl;
    
    // Open connection to read from the vcf file
    std::ifstream* inFile = new std::ifstream(fileName.c_str(), mode);
    
    
    bool gotChromosomeNumber = false;
    int numChromosomes;
    string line;
    int totalVariantNumber = 0;
    while (getline(*inFile, line)) {
        if (line[0] == '#') 
            std::cout << line << std::endl;  
        else {
            totalVariantNumber++;
            FilterResult result;
            std::vector<std::string> fields = split(line, '\t');
            if (!gotChromosomeNumber) {
                const std::vector<std::string>::size_type numSamples = fields.size() - NUM_NON_GENOTYPE_COLUMNS;
                numVariantsPerHetCount.assign(numSamples + 1, 0);
                numChromosomes = (int)numSamples * 2;
                std::cerr << "Number of chromosomes: " << numChromosomes << std::endl;
                gotChromosomeNumber = true;
            }
            result.overallQuality = atoi(fields[5].c_str());
            
            
            if (result.overallQuality >= MIN_OVERALL_VARIANT_PHRED_QUAL) {
                result.overallDepthPassed = testOverallReadDepth(opt::max_overall_depth,opt::min_overall_depth,fields[7]);
                result.biallelicPassed = testBiallelic(fields[4]);
            }
                
            if (result.biallelicPassed) 
                result.counts = getThisVariantCounts(fields);
            
            
            if (result.biallelicPassed && result.counts.overall <= (numChromosomes - opt::min_copies) && result.counts.overall >= opt::min_copies) {
                if (result.counts.minimumDepthInAnIndividual >= opt::min_depth_in_any_individual) {
                    // filter out sites where more than MAX_NUM_HET individuals are heterozygous
                    bool mnhPassed = testMaxNumHet(result, depthsHetFailed, depthsHetPassed, numVariantsPerHetCount, opt::max_het_indiv,num_indiv_het_vs_depth);
                    if (result.overallDepthPassed && mnhPassed) {
                        std::cout << line << std::endl;
                    }
                }
            }  
        }
    }
    
    std::cerr << "Finished filtering; tabulating depths\n" << std::endl;
    // Does the same as R function table
    std::map<int, int> tableHetFailed = tabulateVector(depthsHetFailed);
    std::map<int, int> tableHetPassed = tabulateVector(depthsHetPassed);
    
    std::ios_base::openmode mode_out = std::ios_base::out;
    string hetFailedFileName = fileRoot + ".het_filter.failed_max" + numToString<int>(opt::max_het_indiv);
    std::ofstream* pHetFailOutFile = new std::ofstream(hetFailedFileName.c_str(), mode_out);
    *pHetFailOutFile << "# Failed HetFilter:" << fileName << std::endl;
    *pHetFailOutFile << "Depth\tNum_variants" << std::endl;
    for (std::map<int, int>::const_iterator iter = tableHetFailed.begin(); iter != tableHetFailed.end(); ++iter) {
        *pHetFailOutFile << iter->first << "\t" << iter->second << std::endl;
    }


    string hetPassedFileName = fileRoot + ".het_filter.passed_max" + numToString<int>(opt::max_het_indiv);
    std::ofstream* pHetPassOutFile = new std::ofstream(hetPassedFileName.c_str(), mode_out);
    *pHetPassOutFile << "# Passed HetFilter:" << fileName << std::endl;
    *pHetPassOutFile << "Depth\tNum_variants" << std::endl;
    for (std::map<int, int>::const_iterator iter = tableHetPassed.begin(); iter != tableHetPassed.end(); ++iter) {
        *pHetPassOutFile << iter->first << "\t" << iter->second << std::endl;
    }
    
    string hetVarCountName = fileRoot + ".het_filter.variants_per_het_count_max" + numToString<int>(opt::max_het_indiv);;
    std::ofstream* pHetVarCountFile = new std::ofstream(hetVarCountName.c_str(), mode_out);
    *pHetVarCountFile << "# Number of variants per each het count: " << fileName << std::endl;
    *pHetVarCountFile << "Num_hets\tNum_variants" << std::endl;
    for (std::vector<int>::size_type i = 0; i != numVariantsPerHetCount.size(); i++) {
        *pHetVarCountFile << i << "\t" << numVariantsPerHetCount[i] << std::endl;
    }
    
    string hetDepthScatterplotName = fileRoot + ".het_filter.depth_scatterplot" + numToString<int>(opt::max_het_indiv);;
    std::ofstream* pHetDepthScatterplotFile = new std::ofstream(hetDepthScatterplotName.c_str(), mode_out);
    *pHetDepthScatterplotFile << "# Number of hets and depth for individual variants for a scatterplot: " << fileName << std::endl;
    *pHetDepthScatterplotFile << "Num_hets\tDepth" << std::endl;
    print_matrix<std::vector<std::vector<int> >&>(num_indiv_het_vs_depth, *pHetDepthScatterplotFile);
    
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x3a8, %rsp            # imm = 0x3A8
callq 0x4fb21
leaq 0x8f2af(%rip), %rsi     # 0xde390
leaq 0x80(%rsp), %rbx
movq %rbx, %rdi
callq 0x8600
leaq 0x138(%rsp), %rdi
movq %rbx, %rsi
callq 0x404d7
xorps %xmm0, %xmm0
movaps %xmm0, 0xe0(%rsp)
andq $0x0, 0xf0(%rsp)
movaps %xmm0, 0xc0(%rsp)
andq $0x0, 0xd0(%rsp)
movaps %xmm0, (%rsp)
andq $0x0, 0x10(%rsp)
movaps %xmm0, 0xa0(%rsp)
andq $0x0, 0xb0(%rsp)
movq 0x8dea0(%rip), %rdi     # 0xdcfe8
leaq 0x52459(%rip), %rsi     # 0xa15a8
callq 0x8480
leaq 0x80(%rsp), %rsi
movq %rax, %rdi
callq 0x8430
movq %rax, %rdi
callq 0x8230
movq 0x8de75(%rip), %rdi     # 0xdcfe8
leaq 0x52479(%rip), %rsi     # 0xa15f3
callq 0x8480
movl 0x8e3f3(%rip), %esi     # 0xdd578
movq %rax, %rdi
callq 0x8840
movq %rax, %rdi
callq 0x8230
movq 0x8de4c(%rip), %rdi     # 0xdcfe8
leaq 0x5249c(%rip), %rsi     # 0xa163f
callq 0x8480
movl 0x8e3ce(%rip), %esi     # 0xdd57c
movq %rax, %rdi
callq 0x8840
movq %rax, %rdi
callq 0x8230
movq 0x8de23(%rip), %rdi     # 0xdcfe8
leaq 0x524b3(%rip), %rsi     # 0xa167f
callq 0x8480
movl 0x8e3a9(%rip), %esi     # 0xdd580
movq %rax, %rdi
callq 0x8840
movq %rax, %rdi
callq 0x8230
movq 0x8ddfa(%rip), %rdi     # 0xdcfe8
leaq 0x5251c(%rip), %rsi     # 0xa1711
callq 0x8480
movl 0x8e384(%rip), %esi     # 0xdd584
movq %rax, %rdi
callq 0x8840
leaq 0x52524(%rip), %rsi     # 0xa1733
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movl $0x208, %edi            # imm = 0x208
callq 0x8490
movq %rax, %r15
movq 0x80(%rsp), %rsi
pushq $0x8
popq %rdx
movq %rax, %rdi
callq 0x8890
leaq 0x168(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x1a0(%rsp), %rbx
xorl %ebp, %ebp
leaq 0x158(%rsp), %r14
movq 0x8dd4c(%rip), %r12     # 0xdcfb8
movq %r15, %rdi
movq %r14, %rsi
callq 0x80a0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x4f446
movq 0x158(%rsp), %rax
cmpb $0x23, (%rax)
jne 0x4f2ab
movq %r12, %rdi
movq %r14, %rsi
callq 0x8430
movq %rax, %rdi
callq 0x8230
jmp 0x4f26c
leaq 0x198(%rsp), %rdi
callq 0x4a6c6
leaq 0x60(%rsp), %rdi
movq %r14, %rsi
pushq $0x9
popq %rdx
callq 0x40349
testb $0x1, %bpl
jne 0x4f326
movq 0x68(%rsp), %r13
subq 0x60(%rsp), %r13
sarq $0x5, %r13
leaq -0x8(%r13), %rsi
andl $0x0, 0x2a8(%rsp)
movq %rsp, %rdi
leaq 0x2a8(%rsp), %rdx
callq 0x44dfe
movq 0x8dce9(%rip), %rdi     # 0xdcfe8
leaq 0x5131d(%rip), %rsi     # 0xa0623
callq 0x8480
leal -0x12(,%r13,2), %r13d
movq %rax, %rdi
movl %r13d, %esi
callq 0x8840
movq %rax, %rdi
callq 0x8230
movq 0x60(%rsp), %rbp
movq 0xa0(%rbp), %rdi
callq 0x86f0
movl %eax, 0x198(%rsp)
cmpl $0x1d, %eax
jle 0x4f378
movl 0x8e22f(%rip), %edi     # 0xdd578
addq $0xe0, %rbp
xorl %esi, %esi
movq %rbp, %rdx
callq 0x41f6c
movb %al, 0x19d(%rsp)
movq 0x60(%rsp), %rdi
subq $-0x80, %rdi
callq 0x41f35
movb %al, 0x2a0(%rsp)
jmp 0x4f37f
movb 0x2a0(%rsp), %al
leaq 0x2a8(%rsp), %rbp
testb $0x1, %al
je 0x4f3b2
movq %rbp, %rdi
leaq 0x60(%rsp), %rsi
callq 0x40d83
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x4e5f6
movq %rbp, %rdi
callq 0x289b4
movb 0x2a0(%rsp), %al
testb $0x1, %al
je 0x4f42c
movl 0x1a0(%rsp), %eax
movl 0x8e1b9(%rip), %ecx     # 0xdd57c
cmpl %ecx, %eax
jl 0x4f42c
movl %r13d, %edx
subl %ecx, %edx
cmpl %edx, %eax
jg 0x4f42c
movl 0x1a4(%rsp), %eax
cmpl 0x8e1a3(%rip), %eax     # 0xdd580
jl 0x4f42c
movl 0x8e19e(%rip), %r8d     # 0xdd584
leaq 0x198(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
movq %rsp, %rcx
leaq 0xa0(%rsp), %r9
callq 0x41ff6
andb 0x19d(%rsp), %al
cmpb $0x1, %al
jne 0x4f42c
movq %r12, %rdi
movq %r14, %rsi
callq 0x8430
movq %rax, %rdi
callq 0x8230
leaq 0x60(%rsp), %rdi
callq 0x28a08
movq %rbx, %rdi
callq 0x289b4
movb $0x1, %bpl
jmp 0x4f26c
movq 0x8db9b(%rip), %rdi     # 0xdcfe8
leaq 0x533ac(%rip), %rsi     # 0xa2800
callq 0x8480
movq %rax, %rdi
callq 0x8230
leaq 0x198(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x420f5
leaq 0x2a8(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x420f5
leaq 0x53395(%rip), %rdx     # 0xa2827
leaq 0x118(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x28806
movl 0x8e0d7(%rip), %esi     # 0xdd584
leaq 0x40(%rsp), %rdi
callq 0x28ad3
leaq 0x60(%rsp), %rdi
leaq 0x118(%rsp), %rsi
leaq 0x40(%rsp), %rdx
callq 0x28a48
leaq 0x40(%rsp), %rdi
callq 0x8978
leaq 0x118(%rsp), %rdi
callq 0x8978
movl $0x200, %edi            # imm = 0x200
callq 0x8490
movq %rax, %r15
movq 0x60(%rsp), %rsi
pushq $0x10
popq %rdx
movq %rax, %rdi
callq 0x84e0
leaq 0x53335(%rip), %rsi     # 0xa283e
movq %r15, %rdi
callq 0x8480
leaq 0x80(%rsp), %rsi
movq %rax, %rdi
callq 0x8430
movq %rax, %rdi
callq 0x8230
leaq 0x53322(%rip), %rsi     # 0xa2852
movq %r15, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x1b0(%rsp), %r12
leaq 0x4a8cf(%rip), %r14     # 0x99e1e
cmpq %rbx, %r12
je 0x4f58e
movl 0x20(%r12), %esi
movq %r15, %rdi
callq 0x8840
movq %rax, %rdi
movq %r14, %rsi
callq 0x8480
movl 0x24(%r12), %esi
movq %rax, %rdi
callq 0x8840
movq %rax, %rdi
callq 0x8230
movq %r12, %rdi
callq 0x84f0
movq %rax, %r12
jmp 0x4f54f
leaq 0x532d0(%rip), %rdx     # 0xa2865
leaq 0x40(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x28806
movl 0x8dfd7(%rip), %esi     # 0xdd584
leaq 0x20(%rsp), %rdi
callq 0x28ad3
leaq 0x118(%rsp), %rdi
leaq 0x40(%rsp), %rsi
leaq 0x20(%rsp), %rdx
callq 0x28a48
leaq 0x20(%rsp), %rdi
callq 0x8978
leaq 0x40(%rsp), %rdi
callq 0x8978
movl $0x200, %edi            # imm = 0x200
callq 0x8490
movq %rax, %rbx
movq 0x118(%rsp), %rsi
pushq $0x10
popq %rdx
movq %rax, %rdi
callq 0x84e0
leaq 0x53273(%rip), %rsi     # 0xa287c
movq %rbx, %rdi
callq 0x8480
leaq 0x80(%rsp), %rsi
movq %rax, %rdi
callq 0x8430
movq %rax, %rdi
callq 0x8230
leaq 0x53222(%rip), %rsi     # 0xa2852
movq %rbx, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
leaq 0x2b0(%rsp), %r12
movq 0x10(%r12), %r15
leaq 0x4a7ca(%rip), %r14     # 0x99e1e
cmpq %r12, %r15
je 0x4f691
movl 0x20(%r15), %esi
movq %rbx, %rdi
callq 0x8840
movq %rax, %rdi
movq %r14, %rsi
callq 0x8480
movl 0x24(%r15), %esi
movq %rax, %rdi
callq 0x8840
movq %rax, %rdi
callq 0x8230
movq %r15, %rdi
callq 0x84f0
movq %rax, %r15
jmp 0x4f654
leaq 0x531f8(%rip), %rdx     # 0xa2890
leaq 0x20(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x28806
movl 0x8ded4(%rip), %esi     # 0xdd584
leaq 0xf8(%rsp), %rdi
callq 0x28ad3
leaq 0x40(%rsp), %rdi
leaq 0x20(%rsp), %rsi
leaq 0xf8(%rsp), %rdx
callq 0x28a48
leaq 0xf8(%rsp), %rdi
callq 0x8978
leaq 0x20(%rsp), %rdi
callq 0x8978
movl $0x200, %edi            # imm = 0x200
callq 0x8490
movq %rax, %rbx
movq 0x40(%rsp), %rsi
pushq $0x10
popq %rdx
movq %rax, %rdi
callq 0x84e0
leaq 0x531a8(%rip), %rsi     # 0xa28b7
movq %rbx, %rdi
callq 0x8480
leaq 0x80(%rsp), %rsi
movq %rax, %rdi
callq 0x8430
movq %rax, %rdi
callq 0x8230
leaq 0x531ab(%rip), %rsi     # 0xa28e1
movq %rbx, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
xorl %r14d, %r14d
leaq 0x4a6ce(%rip), %r15     # 0x99e1e
movq 0x8(%rsp), %rax
subq (%rsp), %rax
sarq $0x2, %rax
cmpq %rax, %r14
je 0x4f795
movq %rbx, %rdi
movq %r14, %rsi
callq 0x8320
movq %rax, %rdi
movq %r15, %rsi
callq 0x8480
movq (%rsp), %rcx
movl (%rcx,%r14,4), %esi
movq %rax, %rdi
callq 0x8840
movq %rax, %rdi
callq 0x8230
incq %r14
jmp 0x4f750
leaq 0x5315b(%rip), %rdx     # 0xa28f7
leaq 0xf8(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x28806
movl 0x8ddcd(%rip), %esi     # 0xdd584
leaq 0x178(%rsp), %rdi
callq 0x28ad3
leaq 0x20(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
leaq 0x178(%rsp), %rdx
callq 0x28a48
leaq 0x178(%rsp), %rdi
callq 0x8978
leaq 0xf8(%rsp), %rdi
callq 0x8978
movl $0x200, %edi            # imm = 0x200
callq 0x8490
movq %rax, %rbx
movq 0x20(%rsp), %rsi
pushq $0x10
popq %rdx
movq %rax, %rdi
callq 0x84e0
leaq 0x530f9(%rip), %rsi     # 0xa2915
movq %rbx, %rdi
callq 0x8480
leaq 0x80(%rsp), %rsi
movq %rax, %rdi
callq 0x8430
movq %rax, %rdi
callq 0x8230
leaq 0x53119(%rip), %rsi     # 0xa295c
movq %rbx, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
leaq 0xa0(%rsp), %rdi
movq %rbx, %rsi
callq 0x48828
leaq 0x20(%rsp), %rdi
callq 0x8978
leaq 0x40(%rsp), %rdi
callq 0x8978
leaq 0x118(%rsp), %rdi
callq 0x8978
leaq 0x60(%rsp), %rdi
callq 0x8978
leaq 0x2a8(%rsp), %rdi
callq 0x44472
leaq 0x198(%rsp), %rdi
callq 0x44472
leaq 0x158(%rsp), %rdi
callq 0x8978
leaq 0xa0(%rsp), %rdi
callq 0x3b73c
movq %rsp, %rdi
callq 0x2aef2
leaq 0xc0(%rsp), %rdi
callq 0x2aef2
leaq 0xe0(%rsp), %rdi
callq 0x2aef2
leaq 0x138(%rsp), %rdi
callq 0x8978
leaq 0x80(%rsp), %rdi
callq 0x8978
xorl %eax, %eax
addq $0x3a8, %rsp            # imm = 0x3A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x4fa43
jmp 0x4fa43
jmp 0x4fa43
jmp 0x4fa43
movq %rax, %r14
jmp 0x4fa50
jmp 0x4fa76
movq %rax, %r14
movl $0x200, %esi            # imm = 0x200
movq %rbx, %rdi
callq 0x84a0
jmp 0x4fa65
movq %rax, %r14
leaq 0x178(%rsp), %rdi
callq 0x8978
jmp 0x4f95d
movq %rax, %r14
leaq 0xf8(%rsp), %rdi
jmp 0x4fa6a
jmp 0x4fa7b
movq %rax, %r14
movl $0x200, %esi            # imm = 0x200
movq %rbx, %rdi
callq 0x84a0
jmp 0x4fa7e
movq %rax, %r14
leaq 0xf8(%rsp), %rdi
callq 0x8978
jmp 0x4f999
movq %rax, %r14
leaq 0x20(%rsp), %rdi
jmp 0x4fa83
jmp 0x4fa8a
movq %rax, %r14
movl $0x200, %esi            # imm = 0x200
movq %rbx, %rdi
callq 0x84a0
jmp 0x4fa8d
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0x8978
jmp 0x4f9cf
movq %rax, %r14
leaq 0x40(%rsp), %rdi
jmp 0x4fa95
jmp 0x4fa9c
movq %rax, %r14
movl $0x200, %esi            # imm = 0x200
movq %r15, %rdi
callq 0x84a0
jmp 0x4fa9f
movq %rax, %r14
leaq 0x40(%rsp), %rdi
callq 0x8978
jmp 0x4fa05
movq %rax, %r14
leaq 0x118(%rsp), %rdi
jmp 0x4faa4
movq %rax, %r14
jmp 0x4faa9
movq %rax, %r14
jmp 0x4fab6
jmp 0x4fa76
movq %rax, %r14
movl $0x208, %esi            # imm = 0x208
movq %r15, %rdi
callq 0x84a0
jmp 0x4fad0
jmp 0x4fa71
movq %rax, %r14
jmp 0x4fb0c
movq %rax, %r14
leaq 0x60(%rsp), %rdi
callq 0x28a08
movq %rbx, %rdi
callq 0x289b4
jmp 0x4fac3
jmp 0x4fa76
jmp 0x4fa7b
jmp 0x4fa8a
jmp 0x4fa9c
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0x8978
jmp 0x4fa7e
movq %rax, %r14
jmp 0x4fad0
movq %rax, %r14
jmp 0x4fac3
movq %rax, %r14
leaq 0x40(%rsp), %rdi
callq 0x8978
jmp 0x4fa8d
movq %rax, %r14
leaq 0x118(%rsp), %rdi
callq 0x8978
jmp 0x4fa9f
movq %rax, %r14
leaq 0x60(%rsp), %rdi
callq 0x8978
leaq 0x2a8(%rsp), %rdi
callq 0x44472
leaq 0x198(%rsp), %rdi
callq 0x44472
leaq 0x158(%rsp), %rdi
callq 0x8978
leaq 0xa0(%rsp), %rdi
callq 0x3b73c
movq %rsp, %rdi
callq 0x2aef2
leaq 0xc0(%rsp), %rdi
callq 0x2aef2
leaq 0xe0(%rsp), %rdi
callq 0x2aef2
leaq 0x138(%rsp), %rdi
callq 0x8978
leaq 0x80(%rsp), %rdi
callq 0x8978
movq %r14, %rdi
callq 0x8870