// File: /workspace/github_cpp_makefile_star2_O3/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, 0x118(%rsp)
movq %r8, 0x110(%rsp)
movq %rcx, 0x120(%rsp)
movq %rdx, %rbx
movq %rsi, 0x30(%rsp)
movq %rdi, 0x10(%rsp)
callq 0x5060
movq %rax, 0x108(%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, 0x38(%rsp)
movslq (%rbx), %rbx
leaq 0x58(%rsp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x48(%rsp), %rdi
movl $0x1f4, %esi            # imm = 0x1F4
callq 0x55f0
leaq 0xf8(%rsp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0xe8(%rsp), %rdi
movl $0x1f4, %esi            # imm = 0x1F4
callq 0x55f0
leaq 0x98(%rsp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x88(%rsp), %rdi
movl $0x1f4, %esi            # imm = 0x1F4
callq 0x55f0
leaq 0x78(%rsp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movq 0x38(%rsp), %rax
movslq (%rax), %rax
leaq 0x1(,%rax,2), %rsi
leaq 0x68(%rsp), %rdi
callq 0x55f0
movq 0x10(%rsp), %rcx
movq 0x8(%rcx), %rax
cmpq (%rcx), %rax
je 0x13ee1
leaq 0x1(,%rbx,2), %r15
addq %rbx, %rbx
movslq %ebx, %rax
movq %rax, 0x40(%rsp)
movq $0x0, 0x28(%rsp)
movb $0x1, %al
movl %eax, 0x24(%rsp)
leaq 0x420(%rsp), %r12
leaq 0x88(%rsp), %rbp
movl $0x0, 0x1c(%rsp)
movl $0x0, 0x20(%rsp)
movl $0x8, %edx
movq 0x2d570(%rip), %rdi     # 0x40fc0
leaq 0x1f824(%rip), %rsi     # 0x3327b
callq 0x5420
movq 0x10(%rsp), %rax
movq (%rax), %rax
movq 0x28(%rsp), %r13
shlq $0x5, %r13
movq (%rax,%r13), %rsi
movq 0x8(%rax,%r13), %rdx
movq 0x2d543(%rip), %rdi     # 0x40fc0
callq 0x5420
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x53a0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x5030
movq %rax, %rdi
callq 0x5250
leaq 0x180(%rsp), %rbx
movq %rbx, %rdi
callq 0x7710
movq 0x10(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r13), %rsi
movq %rbx, %rdi
movl $0x8, %edx
callq 0x7d44
movq 0x180(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x5, 0x1a0(%rsp,%rax)
je 0x13cf4
movq 0x2d4fa(%rip), %rcx     # 0x40ff0
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x53a0
movsbl %al, %esi
movq 0x2d4dc(%rip), %rdi     # 0x40ff0
callq 0x5030
movq %rax, %rdi
callq 0x5250
movq %rax, %rbx
movl $0x16, %edx
movq %rax, %rdi
leaq 0x1f8fd(%rip), %rsi     # 0x33430
callq 0x5420
movq 0x10(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r13), %rsi
movq 0x8(%rax,%r13), %rdx
movq %rbx, %rdi
callq 0x5420
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x53a0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x5030
movq %rax, %rdi
callq 0x5250
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x53a0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x5030
movq %rax, %rdi
callq 0x5250
jmp 0x13d55
leaq 0x48(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
movq 0x120(%rsp), %rdx
movl $0x21, %ecx
callq 0x6954
movq %r12, %rdi
callq 0x5280
movq 0x48(%rsp), %rsi
movq 0x50(%rsp), %rdx
leaq 0x430(%rsp), %rdi
callq 0x5420
incl 0x20(%rsp)
movq %r12, %rdi
movq %rbp, %rsi
movl $0x4e, %edx
callq 0x56c0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x13cd8
movq 0x90(%rsp), %rax
cmpq %r15, %rax
jb 0x13bec
xorl %ebx, %ebx
cmpq 0x40(%rsp), %rax
je 0x13ccf
xorl %ebx, %ebx
leaq 0x160(%rsp), %r14
movq %r14, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
movq %r15, %rcx
callq 0x53e0
leaq 0x68(%rsp), %rdi
movq %r14, %rsi
callq 0x5470
movq 0x160(%rsp), %rdi
leaq 0x170(%rsp), %rax
cmpq %rax, %rdi
je 0x13c75
movq 0x170(%rsp), %rsi
incq %rsi
callq 0x53c0
leaq 0x68(%rsp), %r14
movq %r14, %rdi
callq 0x68d8
movq %r14, %rdi
leaq 0xf(%rsp), %rsi
callq 0x8a8b
testl %eax, %eax
jne 0x13d39
movsbl 0xf(%rsp), %edx
movzbl 0x24(%rsp), %ecx
andl $0x1, %ecx
leaq 0x128(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0xa21e
incq %rbx
movq 0x90(%rsp), %rax
subq 0x40(%rsp), %rax
cmpq %rbx, %rax
ja 0x13c2a
addl %ebx, 0x1c(%rsp)
jmp 0x13bec
movq %r12, %rdi
movq 0x2d2a6(%rip), %rsi     # 0x40f88
callq 0x52c0
leaq 0x4a0(%rsp), %rdi
callq 0x5120
leaq 0x308(%rsp), %rdi
callq 0x5140
cmpl $-0x1, %eax
je 0x13dd5
movq 0x10(%rsp), %rax
movq (%rax), %rsi
addq %r13, %rsi
leaq 0x180(%rsp), %rdi
leaq 0x48(%rsp), %rdx
leaq 0xe8(%rsp), %rcx
callq 0x7086
testl %eax, %eax
je 0x13baa
jmp 0x13d55
movq %r12, %rdi
movq 0x2d245(%rip), %rsi     # 0x40f88
callq 0x52c0
leaq 0x4a0(%rsp), %rdi
callq 0x5120
xorl %ebx, %ebx
leaq 0x2ce9a(%rip), %rax     # 0x40bf8
movq %rax, 0x308(%rsp)
leaq 0x2ceb3(%rip), %rax     # 0x40c20
movq %rax, 0x318(%rsp)
movq $0x0, 0x310(%rsp)
leaq 0x180(%rsp), %rdi
leaq 0x2cda8(%rip), %rsi     # 0x40b38
callq 0x7922
leaq 0x318(%rsp), %rdi
callq 0x5120
testb %bl, %bl
je 0x1401a
movq 0x28(%rsp), %rdx
incq %rdx
movq 0x10(%rsp), %rcx
movq 0x8(%rcx), %rax
subq (%rcx), %rax
sarq $0x5, %rax
movq %rdx, 0x28(%rsp)
cmpq %rdx, %rax
ja 0x13a44
jmp 0x13ee1
leaq 0x180(%rsp), %rdi
callq 0x77fa
movl $0x6, %edx
movq 0x2d1d2(%rip), %rdi     # 0x40fc0
leaq 0x1fd94(%rip), %rsi     # 0x33b89
callq 0x5420
movq 0x2d1bf(%rip), %rdi     # 0x40fc0
movl 0x1c(%rsp), %esi
callq 0x5690
movq %rax, %rbx
movl $0xc, %edx
movq %rax, %rdi
leaq 0x1fd74(%rip), %rsi     # 0x33b90
callq 0x5420
movq %rbx, %rdi
movl 0x20(%rsp), %esi
callq 0x5690
movq %rax, %rbx
movl $0xa, %edx
movq %rax, %rdi
leaq 0x1fd8f(%rip), %rsi     # 0x33bce
callq 0x5420
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x53a0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x5030
movq %rax, %rdi
callq 0x5250
movq 0x140(%rsp), %rsi
movq 0x2d146(%rip), %rdi     # 0x40fc0
callq 0x5240
movq %rax, %rbx
movl $0x14, %edx
movq %rax, %rdi
leaq 0x1fd28(%rip), %rsi     # 0x33bb9
callq 0x5420
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x53a0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x5030
movq %rax, %rdi
callq 0x5250
leaq 0x128(%rsp), %rdi
movq 0x110(%rsp), %rsi
callq 0xa2f0
movb $0x1, %bl
movl $0x0, 0x24(%rsp)
jmp 0x13d57
leaq 0x128(%rsp), %rdi
movq 0x118(%rsp), %rsi
callq 0xa3ea
cmpb $0x0, 0x5e8(%rsp)
je 0x13f7d
leaq 0xd8(%rsp), %r14
movq %r14, -0x10(%r14)
movq 0x30(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq 0xc8(%rsp), %rdi
callq 0x8566
leaq 0x1fcaa(%rip), %rsi     # 0x33bd9
leaq 0xc8(%rsp), %rdi
callq 0x5710
leaq 0x128(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x8fc3
movl %eax, %ebp
movq 0xc8(%rsp), %rdi
cmpq %r14, %rdi
je 0x13f70
movq 0xd8(%rsp), %rsi
incq %rsi
callq 0x53c0
movl $0x1, %ebx
testl %ebp, %ebp
jne 0x1401f
leaq 0xb8(%rsp), %r14
movq %r14, -0x10(%r14)
movq 0x30(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq 0xa8(%rsp), %rdi
callq 0x8566
leaq 0x21da2(%rip), %rsi     # 0x35d4e
leaq 0xa8(%rsp), %rdi
callq 0x5710
movq 0x5e0(%rsp), %rax
movq 0x38(%rsp), %rcx
movl (%rcx), %edx
movss (%rax), %xmm0
leaq 0x128(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x8b31
movl %eax, %ebp
movq 0xa8(%rsp), %rdi
cmpq %r14, %rdi
je 0x14000
movq 0xb8(%rsp), %rsi
incq %rsi
callq 0x53c0
movl $0x1, %ebx
testl %ebp, %ebp
jne 0x1401f
xorl %ebx, %ebx
movq 0x108(%rsp), %rdi
callq 0x8320
jmp 0x1401f
movl $0x1, %ebx
movq 0x68(%rsp), %rdi
leaq 0x78(%rsp), %rax
cmpq %rax, %rdi
je 0x1403b
movq 0x78(%rsp), %rsi
incq %rsi
callq 0x53c0
movq 0x88(%rsp), %rdi
leaq 0x98(%rsp), %rax
cmpq %rax, %rdi
je 0x14060
movq 0x98(%rsp), %rsi
incq %rsi
callq 0x53c0
movq 0xe8(%rsp), %rdi
leaq 0xf8(%rsp), %rax
cmpq %rax, %rdi
je 0x14085
movq 0xf8(%rsp), %rsi
incq %rsi
callq 0x53c0
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x140a1
movq 0x58(%rsp), %rsi
incq %rsi
callq 0x53c0
leaq 0x128(%rsp), %rdi
callq 0x13868
movl %ebx, %eax
addq $0x5a8, %rsp            # imm = 0x5A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x140c4
movq %rax, %rbx
movq 0xc8(%rsp), %rdi
cmpq %r14, %rdi
je 0x141ab
movq 0xd8(%rsp), %rsi
jmp 0x14100
jmp 0x140e4
movq %rax, %rbx
movq 0xa8(%rsp), %rdi
cmpq %r14, %rdi
je 0x141ab
movq 0xb8(%rsp), %rsi
incq %rsi
callq 0x53c0
jmp 0x141ab
jmp 0x14131
movq %rax, %rbx
jmp 0x141c7
movq %rax, %rbx
jmp 0x141ec
movq %rax, %rbx
jmp 0x14211
jmp 0x14131
jmp 0x14131
jmp 0x1413f
jmp 0x14136
jmp 0x14136
movq %rax, %rbx
jmp 0x141ab
movq %rax, %rbx
jmp 0x14163
jmp 0x1413f
jmp 0x1413f
movq %rax, %rbx
movq 0x2ce3f(%rip), %rsi     # 0x40f88
leaq 0x420(%rsp), %rdi
callq 0x52c0
leaq 0x4a0(%rsp), %rdi
callq 0x5120
leaq 0x180(%rsp), %rdi
leaq 0x2ca86(%rip), %rax     # 0x40bf8
movq %rax, 0x188(%rdi)
leaq 0x2caa0(%rip), %rax     # 0x40c20
movq %rax, 0x198(%rdi)
movq $0x0, 0x190(%rdi)
leaq 0x2c99f(%rip), %rsi     # 0x40b38
callq 0x7922
leaq 0x318(%rsp), %rdi
callq 0x5120
movq 0x68(%rsp), %rdi
leaq 0x78(%rsp), %rax
cmpq %rax, %rdi
je 0x141c7
movq 0x78(%rsp), %rsi
incq %rsi
callq 0x53c0
movq 0x88(%rsp), %rdi
leaq 0x98(%rsp), %rax
cmpq %rax, %rdi
je 0x141ec
movq 0x98(%rsp), %rsi
incq %rsi
callq 0x53c0
movq 0xe8(%rsp), %rdi
leaq 0xf8(%rsp), %rax
cmpq %rax, %rdi
je 0x14211
movq 0xf8(%rsp), %rsi
incq %rsi
callq 0x53c0
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x1422d
movq 0x58(%rsp), %rsi
incq %rsi
callq 0x53c0
leaq 0x128(%rsp), %rdi
callq 0x13868
movq %rbx, %rdi
callq 0x56a0
nop