// File: /workspace/github_cpp_makefile_star2_O1/simonrharris[P]SKA/src/sk_fastq.cpp
// Function: fastqToKmers(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::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, int const&, int const&, int const&, int const&, float const&, bool)
int fastqToKmers(const std::vector < std::string > & fastqs, const std::string & outfilename, const int & kmerlen, const int & userminquality, const int & userfilecutoff, const int & usercovcutoff, const float & userminmaf, const bool printAlleles)
{

	const std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();//start the clock
	
	std::unordered_map < std::string, std::array < int, 8 > > kmerMap;//create a map to store the kmers for each base
	int substringlength=(kmerlen*2)+1;
	int numseqs=0;
	int numbases=0;
	int numreadbases=0;

	std::string sequence;
	sequence.reserve(500);
	std::string quality;
	quality.reserve(500);
	std::string subsequence;
	subsequence.reserve(500);
	std::string kmer;
	kmer.reserve((kmerlen*2)+1);
	char base;
	bool isFirst=true;

	for (int s = 0; s < fastqs.size(); ++s){
		
		std::cout << "Reading " << fastqs[s] << std::endl;
		igzstream gzfileStream;
		gzfileStream.open(fastqs[s].c_str());//open the fastq file
		if (gzfileStream.fail()){
			std::cerr << std::endl << "Error: Failed to open " << fastqs[s] << std::endl << std::endl;
			return 1;
		}

		while (gzfileStream.peek()!=EOF){
			if (readNextFastqSequence(gzfileStream, fastqs[s], sequence, quality)){return 1;};//read the next fastq sequence

			numseqs++;
			numreadbases+=sequence.length();

			lowqualitytoN(sequence, quality, userminquality);
			
			std::stringstream sequencestream;
			sequencestream << sequence;//convert the sequence to stringstream
			
			while (std::getline(sequencestream, subsequence, 'N')){//for each subsequence separated by Ns
				
				if (subsequence.length()<substringlength){//if the subsequence is too small then continue
					continue;
				}
				
				int i=0;
				
				for (i=0; i<subsequence.length()-(substringlength-1); ++i){//for each base in the subsequence
					
					kmer=subsequence.substr(i,substringlength);//extract the kmer from the subsequence
					
					reverseComplementIfMin(kmer);//If the rev comp of the kmer is 'smaller' then rev comp the kmer

					if(extractMiddleBase(kmer, base)){return 1;}//extract the middle base from the kmer

					addKmerToBaseArrayMap(kmerMap, kmer, base, isFirst);//add the kmer and base to the map
					
				}
				numbases+=i;
			}
    	}
		gzfileStream.close();//close the file
		isFirst=false;

		std::cout << "Added " << numbases << " kmers from " << numseqs << " sequences" << std::endl;
		std::cout << kmerMap.size() << " unique kmers in map" << std::endl;

		applyFileKmerArrayMapFilters(kmerMap, userfilecutoff);//Filter file kmers to remove those below the maf and file cov cutoff thresholds
		
	}

	applyFinalKmerArrayMapFilters(kmerMap, usercovcutoff);//Filter the kmers to remove those below the maf and cov cutoff thresholds
	
	if(printAlleles){
		if(printKmerAlleleFrequencies(kmerMap, outfilename+"_alleles.tsv")){return 1;}//print the kmers to file
	}

	if(printKmerFile(kmerMap, outfilename+".skf", kmerlen, userminmaf)){return 1;}//print the kmers to file

	printDuration(start);//stop the clock
	
	return 0;
	
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x5a8, %rsp            # imm = 0x5A8
movq %r9, 0x108(%rsp)
movq %r8, 0x110(%rsp)
movq %rcx, 0x120(%rsp)
movq %rdx, %rbx
movq %rsi, 0x28(%rsp)
movq %rdi, %rbp
callq 0x5060
movq %rax, 0x100(%rsp)
leaq 0x158(%rsp), %rax
movq %rax, -0x30(%rax)
movq $0x1, -0x28(%rax)
xorps %xmm0, %xmm0
movups %xmm0, -0x20(%rax)
movl $0x3f800000, -0x10(%rax) # imm = 0x3F800000
movups %xmm0, -0x8(%rax)
movq %rbx, 0x30(%rsp)
movslq (%rbx), %rbx
leaq 0x70(%rsp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x60(%rsp), %rdi
movl $0x1f4, %esi            # imm = 0x1F4
callq 0x55f0
leaq 0xf0(%rsp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0xe0(%rsp), %rdi
movl $0x1f4, %esi            # imm = 0x1F4
callq 0x55f0
leaq 0x50(%rsp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x40(%rsp), %rdi
movl $0x1f4, %esi            # imm = 0x1F4
callq 0x55f0
leaq 0x90(%rsp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movq 0x30(%rsp), %rax
movslq (%rax), %rax
leaq 0x1(,%rax,2), %rsi
leaq 0x80(%rsp), %rdi
callq 0x55f0
movq 0x8(%rbp), %rax
cmpq (%rbp), %rax
je 0x1407f
leaq 0x1(,%rbx,2), %r12
addq %rbx, %rbx
movslq %ebx, %rax
movq %rax, 0x38(%rsp)
movq $0x0, 0x18(%rsp)
movb $0x1, %al
movl %eax, 0x14(%rsp)
leaq 0x180(%rsp), %rbx
leaq 0x40(%rsp), %r13
movl $0x0, 0xc(%rsp)
movl $0x0, 0x10(%rsp)
movq %rbp, 0x118(%rsp)
movl $0x8, %edx
movq 0x2d3e1(%rip), %rdi     # 0x40fc0
leaq 0x1f695(%rip), %rsi     # 0x3327b
callq 0x5420
movq (%rbp), %rax
movq 0x18(%rsp), %rcx
shlq $0x5, %rcx
movq (%rax,%rcx), %rsi
movq %rcx, 0x20(%rsp)
movq 0x8(%rax,%rcx), %rdx
movq 0x2d3b3(%rip), %rdi     # 0x40fc0
callq 0x5420
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x53a0
movsbl %al, %esi
movq %r14, %rdi
callq 0x5030
movq %rax, %rdi
callq 0x5250
movq %rbx, %rdi
callq 0x7742
movq (%rbp), %rax
movq 0x20(%rsp), %rcx
movq (%rax,%rcx), %rsi
movq %rbx, %rdi
movl $0x8, %edx
callq 0x7d76
movq 0x180(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x5, 0x1a0(%rsp,%rax)
je 0x13db3
movq 0x2d371(%rip), %rcx     # 0x40ff0
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x53a0
movsbl %al, %esi
movq 0x2d353(%rip), %rdi     # 0x40ff0
callq 0x5030
movq %rax, %rdi
callq 0x5250
movq %rax, %r14
movl $0x16, %edx
movq %rax, %rdi
leaq 0x1f774(%rip), %rsi     # 0x33430
callq 0x5420
movq (%rbp), %rax
movq 0x20(%rsp), %rcx
movq (%rax,%rcx), %rsi
movq 0x8(%rax,%rcx), %rdx
movq %r14, %rdi
callq 0x5420
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x53a0
movsbl %al, %esi
movq %r14, %rdi
callq 0x5030
movq %rax, %rdi
callq 0x5250
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x53a0
movsbl %al, %esi
movq %r14, %rdi
callq 0x5030
movq %rax, %rdi
callq 0x5250
xorl %ebx, %ebx
leaq 0x2cec0(%rip), %rax     # 0x40bf8
movq %rax, 0x308(%rsp)
leaq 0x2ced9(%rip), %rax     # 0x40c20
movq %rax, 0x318(%rsp)
movq $0x0, 0x310(%rsp)
leaq 0x180(%rsp), %rdi
leaq 0x2cdce(%rip), %rsi     # 0x40b38
callq 0x7954
leaq 0x318(%rsp), %rdi
callq 0x5120
testb %bl, %bl
je 0x141b8
movq 0x18(%rsp), %rdx
incq %rdx
movq 0x8(%rbp), %rax
subq (%rbp), %rax
sarq $0x5, %rax
movq %rdx, 0x18(%rsp)
cmpq %rdx, %rax
leaq 0x180(%rsp), %rbx
ja 0x13bd3
jmp 0x1407f
leaq 0x308(%rsp), %rdi
callq 0x5140
cmpl $-0x1, %eax
je 0x13f78
movq (%rbp), %rsi
addq 0x20(%rsp), %rsi
movq %rbx, %rdi
leaq 0x60(%rsp), %rdx
leaq 0xe0(%rsp), %rcx
callq 0x70b8
testl %eax, %eax
jne 0x13d2f
leaq 0x60(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
movq 0x120(%rsp), %rdx
movl $0x21, %ecx
callq 0x6982
leaq 0x420(%rsp), %rdi
callq 0x5280
movq 0x60(%rsp), %rsi
movq 0x68(%rsp), %rdx
leaq 0x430(%rsp), %rdi
callq 0x5420
incl 0x10(%rsp)
leaq 0x420(%rsp), %rdi
movq %r13, %rsi
movl $0x4e, %edx
callq 0x56c0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x20(%rax,%rcx), %ebp
testb $0x5, %bpl
jne 0x13f40
cmpq %r12, 0x48(%rsp)
jb 0x13e36
xorl %r14d, %r14d
movq 0x38(%rsp), %rax
cmpq %rax, 0x48(%rsp)
setne %bl
je 0x13f2a
xorl %r14d, %r14d
leaq 0x160(%rsp), %r15
movq %r15, %rdi
movq %r13, %rsi
movq %r14, %rdx
movq %r12, %rcx
callq 0x53e0
leaq 0x80(%rsp), %rdi
movq %r15, %rsi
callq 0x5470
movq 0x160(%rsp), %rdi
leaq 0x170(%rsp), %rax
cmpq %rax, %rdi
je 0x13ece
movq 0x170(%rsp), %rsi
incq %rsi
callq 0x53c0
leaq 0x80(%rsp), %r15
movq %r15, %rdi
callq 0x6905
movq %r15, %rdi
leaq 0xb(%rsp), %rsi
callq 0x8ae7
testl %eax, %eax
jne 0x13f2f
movsbl 0xb(%rsp), %edx
movzbl 0x14(%rsp), %ecx
andl $0x1, %ecx
leaq 0x128(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0xa289
incq %r14
movq 0x48(%rsp), %rax
subq 0x38(%rsp), %rax
cmpq %r14, %rax
seta %bl
ja 0x13e80
addl %r14d, 0xc(%rsp)
testb $0x1, %bl
leaq 0x180(%rsp), %rbx
je 0x13e36
leaq 0x420(%rsp), %rdi
movq 0x2d039(%rip), %rsi     # 0x40f88
callq 0x52c0
leaq 0x4a0(%rsp), %rdi
callq 0x5120
testb $0x5, %bpl
movq 0x118(%rsp), %rbp
jne 0x13db3
jmp 0x13d2f
movq %rbx, %rdi
callq 0x782c
movl $0x6, %edx
movq 0x2d034(%rip), %rdi     # 0x40fc0
leaq 0x1fc06(%rip), %rsi     # 0x33b99
callq 0x5420
movq 0x2d021(%rip), %rdi     # 0x40fc0
movl 0xc(%rsp), %esi
callq 0x5690
movq %rax, %r14
movl $0xc, %edx
movq %rax, %rdi
leaq 0x1fbe6(%rip), %rsi     # 0x33ba0
callq 0x5420
movq %r14, %rdi
movl 0x10(%rsp), %esi
callq 0x5690
movq %rax, %r14
movl $0xa, %edx
movq %rax, %rdi
leaq 0x1fc01(%rip), %rsi     # 0x33bde
callq 0x5420
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x53a0
movsbl %al, %esi
movq %r14, %rdi
callq 0x5030
movq %rax, %rdi
callq 0x5250
movq 0x140(%rsp), %rsi
movq 0x2cfa8(%rip), %rdi     # 0x40fc0
callq 0x5240
movq %rax, %r14
movl $0x14, %edx
movq %rax, %rdi
leaq 0x1fb9a(%rip), %rsi     # 0x33bc9
callq 0x5420
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x53a0
movsbl %al, %esi
movq %r14, %rdi
callq 0x5030
movq %rax, %rdi
callq 0x5250
leaq 0x128(%rsp), %rdi
movq 0x110(%rsp), %rsi
callq 0xa35b
movb $0x1, %bl
movl $0x0, 0x14(%rsp)
jmp 0x13d31
leaq 0x128(%rsp), %rdi
movq 0x108(%rsp), %rsi
callq 0xa44f
cmpb $0x0, 0x5e8(%rsp)
je 0x1411b
leaq 0xd0(%rsp), %r14
movq %r14, -0x10(%r14)
movq 0x28(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq 0xc0(%rsp), %rdi
callq 0x859a
leaq 0x1fb1c(%rip), %rsi     # 0x33be9
leaq 0xc0(%rsp), %rdi
callq 0x5710
leaq 0x128(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x901f
movl %eax, %ebp
movq 0xc0(%rsp), %rdi
cmpq %r14, %rdi
je 0x1410e
movq 0xd0(%rsp), %rsi
incq %rsi
callq 0x53c0
movl $0x1, %ebx
testl %ebp, %ebp
jne 0x141bd
leaq 0xb0(%rsp), %r14
movq %r14, -0x10(%r14)
movq 0x28(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq 0xa0(%rsp), %rdi
callq 0x859a
leaq 0x21c14(%rip), %rsi     # 0x35d5e
leaq 0xa0(%rsp), %rdi
callq 0x5710
movq 0x5e0(%rsp), %rax
movq 0x30(%rsp), %rcx
movl (%rcx), %edx
movss (%rax), %xmm0
leaq 0x128(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x8b8d
movl %eax, %ebp
movq 0xa0(%rsp), %rdi
cmpq %r14, %rdi
je 0x1419e
movq 0xb0(%rsp), %rsi
incq %rsi
callq 0x53c0
movl $0x1, %ebx
testl %ebp, %ebp
jne 0x141bd
xorl %ebx, %ebx
movq 0x100(%rsp), %rdi
callq 0x8354
jmp 0x141bd
movl $0x1, %ebx
movq 0x80(%rsp), %rdi
leaq 0x90(%rsp), %rax
cmpq %rax, %rdi
je 0x141e2
movq 0x90(%rsp), %rsi
incq %rsi
callq 0x53c0
movq 0x40(%rsp), %rdi
leaq 0x50(%rsp), %rax
cmpq %rax, %rdi
je 0x141fe
movq 0x50(%rsp), %rsi
incq %rsi
callq 0x53c0
movq 0xe0(%rsp), %rdi
leaq 0xf0(%rsp), %rax
cmpq %rax, %rdi
je 0x14223
movq 0xf0(%rsp), %rsi
incq %rsi
callq 0x53c0
movq 0x60(%rsp), %rdi
leaq 0x70(%rsp), %rax
cmpq %rax, %rdi
je 0x1423f
movq 0x70(%rsp), %rsi
incq %rsi
callq 0x53c0
leaq 0x128(%rsp), %rdi
callq 0x139f8
movl %ebx, %eax
addq $0x5a8, %rsp            # imm = 0x5A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x14262
movq %rax, %rbx
movq 0xc0(%rsp), %rdi
cmpq %r14, %rdi
je 0x14342
movq 0xd0(%rsp), %rsi
jmp 0x1429e
jmp 0x14282
movq %rax, %rbx
movq 0xa0(%rsp), %rdi
cmpq %r14, %rdi
je 0x14342
movq 0xb0(%rsp), %rsi
incq %rsi
callq 0x53c0
jmp 0x14342
jmp 0x142cd
movq %rax, %rbx
jmp 0x14367
movq %rax, %rbx
jmp 0x14383
movq %rax, %rbx
jmp 0x143a8
jmp 0x142cd
jmp 0x142cd
jmp 0x142dd
jmp 0x142d4
movq %rax, %rbx
jmp 0x14342
jmp 0x142d4
movq %rax, %rbx
jmp 0x14301
jmp 0x142dd
jmp 0x142dd
movq %rax, %rbx
movq 0x2cca1(%rip), %rsi     # 0x40f88
leaq 0x420(%rsp), %rdi
callq 0x52c0
leaq 0x4a0(%rsp), %rdi
callq 0x5120
leaq 0x318(%rsp), %r14
leaq 0x2c8e8(%rip), %rax     # 0x40bf8
movq %rax, -0x10(%r14)
leaq 0x2c905(%rip), %rax     # 0x40c20
movq %rax, (%r14)
movq $0x0, -0x8(%r14)
leaq 0x2c80b(%rip), %rsi     # 0x40b38
leaq 0x180(%rsp), %rdi
callq 0x7954
movq %r14, %rdi
callq 0x5120
movq 0x80(%rsp), %rdi
leaq 0x90(%rsp), %rax
cmpq %rax, %rdi
je 0x14367
movq 0x90(%rsp), %rsi
incq %rsi
callq 0x53c0
movq 0x40(%rsp), %rdi
leaq 0x50(%rsp), %rax
cmpq %rax, %rdi
je 0x14383
movq 0x50(%rsp), %rsi
incq %rsi
callq 0x53c0
movq 0xe0(%rsp), %rdi
leaq 0xf0(%rsp), %rax
cmpq %rax, %rdi
je 0x143a8
movq 0xf0(%rsp), %rsi
incq %rsi
callq 0x53c0
movq 0x60(%rsp), %rdi
leaq 0x70(%rsp), %rax
cmpq %rax, %rdi
je 0x143c4
movq 0x70(%rsp), %rsi
incq %rsi
callq 0x53c0
leaq 0x128(%rsp), %rdi
callq 0x139f8
movq %rbx, %rdi
callq 0x56a0
nopl (%rax)