// File: simonrharris[P]SKA/src/sk_weed.cpp
// Function: addKmersByFilters(std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::less<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>>>>&, 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&, int, int, int&, int)
int addKmersByFilters (std::set < std::string > & myKmerSet, const std::vector < std::string > & myFiles, const int minSamples, const int maxSamples, int & myKmerSize, const int numSamples) {
	std::unordered_map < std::string, int > kmerCountMap;
	std::ifstream myFileStream;

	if (minSamples>0){
		std::cout << "Weeding kmers that are present in fewer than " << minSamples << " samples" << std::endl;
	}
	if (maxSamples<numSamples){
		std::cout << "Weeding kmers that are present in more than " << maxSamples << " samples" << std::endl;
	}

	for (std::vector < std::string >::const_iterator it = myFiles.begin(); it != myFiles.end(); ++it){

		if (openFileStream(*it, myFileStream)){return 1;};

		int kmersize;
		std::vector < std::string > names;
		
		readKmerHeader(myFileStream, kmersize, names);
		
		if (myKmerSize==0){
			myKmerSize=kmersize;
		}
		if (kmersize!=myKmerSize){
			std::cerr << "Files have different kmer sizes" << std::endl << std::endl;
			return 1;
		}

		bool firstkmer=true;
		char base;
		char kmerbuffer[kmersize*2/3];
		char asciibuffer[int(ceil(float(names.size())/6))];
		while (myFileStream.read(asciibuffer, sizeof(asciibuffer))){
			std::string asciibits (asciibuffer, sizeof(asciibuffer));
			std::vector < bool > mybits;
			vectorbool_from_ascii(asciibits, mybits);//read the ascii representation of the taxa to a vector of bools
			int matchcount=std::count(mybits.begin(), mybits.end(), true);
			
			while (myFileStream.peek()!='\n' && myFileStream.get(base)){
				myFileStream.read(kmerbuffer, sizeof(kmerbuffer));
				std::string kmer (kmerbuffer, kmersize*2/3);
				
				std::unordered_map < std::string, int >::iterator kcmit = kmerCountMap.find(kmer);//check if the kmer is in the hash
				if ( kcmit != kmerCountMap.end() ){//if the kmer is not in the hash
					kcmit->second+=matchcount;
				}
				else {
					kmerCountMap.insert(std::make_pair(kmer, matchcount));
				}
			}
			myFileStream.ignore(256,'\n');//skip the end ofline character
    	}
		myFileStream.close();
	}

	std::unordered_map < std::string, int >::iterator kcmit = kmerCountMap.begin();
	std::unordered_map < std::string, int >::iterator kcmend = kmerCountMap.end();

	for (; kcmit!=kcmend; ){
		if (kcmit->second<minSamples || kcmit->second>maxSamples){
			//std::cout << kcmit->first << " " << kcmit->second << std::endl;
			myKmerSet.insert(kcmit->first);
		}
		kmerCountMap.erase(kcmit++);
	}
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x520, %rsp            # imm = 0x520
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl %ecx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movl %r9d, -0x2c(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x4a430
leaq -0x270(%rbp), %rdi
callq 0x65f0
jmp 0x48738
cmpl $0x0, -0x1c(%rbp)
jle 0x487d7
movq 0x3085f(%rip), %rdi     # 0x78fa8
leaq 0x11f90(%rip), %rsi     # 0x5a6e0
callq 0x6520
movq %rax, -0x418(%rbp)
jmp 0x4875e
movq -0x418(%rbp), %rdi
movl -0x1c(%rbp), %esi
callq 0x68d0
movq %rax, -0x420(%rbp)
jmp 0x48776
movq -0x420(%rbp), %rdi
leaq 0x11f8a(%rip), %rsi     # 0x5a70e
callq 0x6520
movq %rax, -0x428(%rbp)
jmp 0x48792
movq -0x428(%rbp), %rdi
movq 0x307f0(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x487a7
jmp 0x487d7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x278(%rbp)
movl %eax, -0x27c(%rbp)
jmp 0x49066
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x278(%rbp)
movl %eax, -0x27c(%rbp)
jmp 0x4905a
movl -0x20(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x48846
movq 0x307c2(%rip), %rdi     # 0x78fa8
leaq 0x11f2a(%rip), %rsi     # 0x5a717
callq 0x6520
movq %rax, -0x430(%rbp)
jmp 0x487fb
movq -0x430(%rbp), %rdi
movl -0x20(%rbp), %esi
callq 0x68d0
movq %rax, -0x438(%rbp)
jmp 0x48813
movq -0x438(%rbp), %rdi
leaq 0x11eed(%rip), %rsi     # 0x5a70e
callq 0x6520
movq %rax, -0x440(%rbp)
jmp 0x4882f
movq -0x440(%rbp), %rdi
movq 0x30753(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x48844
jmp 0x48846
movq -0x18(%rbp), %rdi
callq 0xefe0
movq %rax, -0x288(%rbp)
movq -0x18(%rbp), %rdi
callq 0xf050
movq %rax, -0x290(%rbp)
leaq -0x288(%rbp), %rdi
leaq -0x290(%rbp), %rsi
callq 0xf010
testb $0x1, %al
jne 0x48882
jmp 0x48f38
leaq -0x288(%rbp), %rdi
callq 0xf080
movq %rax, %rdi
leaq -0x270(%rbp), %rsi
movl $0x1, %edx
callq 0xa4f0
movl %eax, -0x444(%rbp)
jmp 0x488aa
movl -0x444(%rbp), %eax
cmpl $0x0, %eax
je 0x488cb
movl $0x1, -0x4(%rbp)
movl $0x1, -0x294(%rbp)
jmp 0x4903d
leaq -0x2b0(%rbp), %rdi
movq %rdi, -0x450(%rbp)
callq 0x1ab40
movq -0x450(%rbp), %rdx
leaq -0x270(%rbp), %rdi
leaq -0x298(%rbp), %rsi
callq 0xcd40
jmp 0x488fa
movq -0x28(%rbp), %rax
cmpl $0x0, (%rax)
jne 0x48928
movl -0x298(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, (%rax)
jmp 0x48928
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x278(%rbp)
movl %eax, -0x27c(%rbp)
jmp 0x48f27
movl -0x298(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpl (%rcx), %eax
je 0x48999
movq 0x306b3(%rip), %rdi     # 0x78ff0
leaq 0x11e00(%rip), %rsi     # 0x5a744
callq 0x6520
movq %rax, -0x458(%rbp)
jmp 0x48952
movq -0x458(%rbp), %rdi
movq 0x30630(%rip), %rsi     # 0x78f90
callq 0x6570
movq %rax, -0x460(%rbp)
jmp 0x4896e
movq -0x460(%rbp), %rdi
movq 0x30614(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x48983
movl $0x1, -0x4(%rbp)
movl $0x1, -0x294(%rbp)
jmp 0x48ef8
movb $0x1, -0x2b1(%rbp)
movl -0x298(%rbp), %eax
addl %eax, %eax
cltq
imulq $0x55555556, %rax, %rax # imm = 0x55555556
movq %rax, %rcx
shrq $0x3f, %rcx
shrq $0x20, %rax
addl %ecx, %eax
movq %rax, -0x478(%rbp)
movq %rsp, %rcx
movq %rcx, -0x2c0(%rbp)
movq %rax, %rdx
addq $0xf, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x470(%rbp)
movq %rcx, %rsp
movq %rax, -0x2c8(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0xb670
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x468(%rbp)
testq %rax, %rax
movss %xmm0, -0x464(%rbp)
js 0x48a3e
movss -0x468(%rbp), %xmm0
movss %xmm0, -0x464(%rbp)
movss -0x464(%rbp), %xmm0
movss 0x10c2e(%rip), %xmm1    # 0x5967c
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
callq 0x60b0
cvttsd2si %xmm0, %eax
movq %rax, -0x488(%rbp)
movq %rax, %rdx
addq $0xf, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x480(%rbp)
movq %rcx, %rsp
movq %rax, -0x2d0(%rbp)
movq -0x488(%rbp), %rdx
movq -0x480(%rbp), %rsi
leaq -0x270(%rbp), %rdi
callq 0x6680
movq %rax, -0x490(%rbp)
jmp 0x48aab
movq -0x490(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x6670
movb %al, -0x491(%rbp)
jmp 0x48ac9
movb -0x491(%rbp), %al
testb $0x1, %al
jne 0x48ad8
jmp 0x48ed6
leaq -0x2f1(%rbp), %rdi
movq %rdi, -0x4a0(%rbp)
callq 0x6910
movq -0x480(%rbp), %rsi
movq -0x488(%rbp), %rdx
movq -0x4a0(%rbp), %rcx
leaq -0x2f0(%rbp), %rdi
callq 0x65e0
jmp 0x48b0e
leaq -0x2f1(%rbp), %rdi
callq 0x65a0
leaq -0x320(%rbp), %rdi
movq %rdi, -0x4a8(%rbp)
callq 0x1acc0
movq -0x4a8(%rbp), %rsi
leaq -0x2f0(%rbp), %rdi
callq 0xbd50
jmp 0x48b42
leaq -0x320(%rbp), %rdi
movq %rdi, -0x4b8(%rbp)
callq 0xf580
movq -0x4b8(%rbp), %rdi
movl %edx, -0x340(%rbp)
movq %rax, -0x348(%rbp)
movl -0x340(%rbp), %eax
movl %eax, -0x330(%rbp)
movq -0x348(%rbp), %rax
movq %rax, -0x338(%rbp)
callq 0xf5c0
movl %edx, -0x360(%rbp)
movq %rax, -0x368(%rbp)
movl -0x360(%rbp), %eax
movl %eax, -0x350(%rbp)
movq -0x368(%rbp), %rax
movq %rax, -0x358(%rbp)
movb $0x1, -0x369(%rbp)
movq -0x338(%rbp), %rdi
movl -0x330(%rbp), %esi
movq -0x358(%rbp), %rdx
movl -0x350(%rbp), %ecx
leaq -0x369(%rbp), %r8
callq 0x1ab80
movq %rax, -0x4b0(%rbp)
jmp 0x48be5
movq -0x4b0(%rbp), %rax
movl %eax, -0x324(%rbp)
leaq -0x270(%rbp), %rdi
callq 0x61c0
movl %eax, -0x4bc(%rbp)
jmp 0x48c06
movl -0x4bc(%rbp), %ecx
xorl %eax, %eax
cmpl $0xa, %ecx
movb %al, -0x4bd(%rbp)
je 0x48c61
leaq -0x270(%rbp), %rdi
leaq -0x2b2(%rbp), %rsi
callq 0x6720
movq %rax, -0x4c8(%rbp)
jmp 0x48c35
movq -0x4c8(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x6670
movb %al, -0x4c9(%rbp)
jmp 0x48c53
movb -0x4c9(%rbp), %al
movb %al, -0x4bd(%rbp)
jmp 0x48c61
movb -0x4bd(%rbp), %al
testb $0x1, %al
jne 0x48c70
jmp 0x48e87
movq -0x478(%rbp), %rdx
movq -0x470(%rbp), %rsi
leaq -0x270(%rbp), %rdi
callq 0x6680
jmp 0x48c8c
movl -0x298(%rbp), %eax
addl %eax, %eax
cltq
imulq $0x55555556, %rax, %rax # imm = 0x55555556
movq %rax, %rcx
shrq $0x3f, %rcx
shrq $0x20, %rax
addl %ecx, %eax
cltq
movq %rax, -0x4e0(%rbp)
leaq -0x391(%rbp), %rdi
movq %rdi, -0x4d8(%rbp)
callq 0x6910
movq -0x470(%rbp), %rsi
movq -0x4e0(%rbp), %rdx
movq -0x4d8(%rbp), %rcx
leaq -0x390(%rbp), %rdi
callq 0x65e0
jmp 0x48ce9
leaq -0x391(%rbp), %rdi
callq 0x65a0
leaq -0x68(%rbp), %rdi
leaq -0x390(%rbp), %rsi
callq 0x4a450
movq %rax, -0x4e8(%rbp)
jmp 0x48d0e
movq -0x4e8(%rbp), %rax
movq %rax, -0x3a0(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x4a4b0
movq %rax, -0x3a8(%rbp)
leaq -0x3a0(%rbp), %rdi
leaq -0x3a8(%rbp), %rsi
callq 0x4a480
testb $0x1, %al
jne 0x48d48
jmp 0x48de5
movl -0x324(%rbp), %eax
movl %eax, -0x4ec(%rbp)
leaq -0x3a0(%rbp), %rdi
callq 0x4a4e0
movl -0x4ec(%rbp), %ecx
addl 0x20(%rax), %ecx
movl %ecx, 0x20(%rax)
jmp 0x48e68
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x278(%rbp)
movl %eax, -0x27c(%rbp)
leaq -0x2f1(%rbp), %rdi
callq 0x65a0
jmp 0x48f27
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x278(%rbp)
movl %eax, -0x27c(%rbp)
jmp 0x48ebc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x278(%rbp)
movl %eax, -0x27c(%rbp)
leaq -0x391(%rbp), %rdi
callq 0x65a0
jmp 0x48ebc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x278(%rbp)
movl %eax, -0x27c(%rbp)
jmp 0x48e79
leaq -0x3d0(%rbp), %rdi
leaq -0x390(%rbp), %rsi
leaq -0x324(%rbp), %rdx
callq 0x4a550
jmp 0x48e01
leaq -0x68(%rbp), %rdi
leaq -0x3d0(%rbp), %rsi
callq 0x4a510
movb %dl, -0x4f9(%rbp)
movq %rax, -0x4f8(%rbp)
jmp 0x48e20
movb -0x4f9(%rbp), %al
movq -0x4f8(%rbp), %rcx
movq %rcx, -0x3e0(%rbp)
movb %al, -0x3d8(%rbp)
leaq -0x3d0(%rbp), %rdi
callq 0x4a590
jmp 0x48e68
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x278(%rbp)
movl %eax, -0x27c(%rbp)
leaq -0x3d0(%rbp), %rdi
callq 0x4a590
jmp 0x48e79
leaq -0x390(%rbp), %rdi
callq 0x6a08
jmp 0x48bf2
leaq -0x390(%rbp), %rdi
callq 0x6a08
jmp 0x48ebc
leaq -0x270(%rbp), %rdi
movl $0x100, %esi            # imm = 0x100
movl $0xa, %edx
callq 0x6340
jmp 0x48e9f
leaq -0x320(%rbp), %rdi
callq 0xf720
leaq -0x2f0(%rbp), %rdi
callq 0x6a08
jmp 0x48a88
leaq -0x320(%rbp), %rdi
callq 0xf720
leaq -0x2f0(%rbp), %rdi
callq 0x6a08
jmp 0x48f27
leaq -0x270(%rbp), %rdi
callq 0x60f0
jmp 0x48ee4
movq -0x2c0(%rbp), %rax
movq %rax, %rsp
movl $0x0, -0x294(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0xfe90
movl -0x294(%rbp), %eax
testl %eax, %eax
jne 0x4903d
jmp 0x48f14
jmp 0x48f16
leaq -0x288(%rbp), %rdi
callq 0xf0a0
jmp 0x48856
leaq -0x2b0(%rbp), %rdi
callq 0xfe90
jmp 0x4905a
leaq -0x68(%rbp), %rdi
callq 0x4a5b0
movq %rax, -0x3e8(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x4a4b0
movq %rax, -0x3f0(%rbp)
leaq -0x3e8(%rbp), %rdi
leaq -0x3f0(%rbp), %rsi
callq 0x4a480
testb $0x1, %al
jne 0x48f74
jmp 0x4902c
leaq -0x3e8(%rbp), %rdi
callq 0x4a4e0
movl 0x20(%rax), %eax
cmpl -0x1c(%rbp), %eax
jl 0x48f9c
leaq -0x3e8(%rbp), %rdi
callq 0x4a4e0
movl 0x20(%rax), %eax
cmpl -0x20(%rbp), %eax
jle 0x48feb
movq -0x10(%rbp), %rax
movq %rax, -0x518(%rbp)
leaq -0x3e8(%rbp), %rdi
callq 0x4a4e0
movq -0x518(%rbp), %rdi
movq %rax, %rsi
callq 0xf310
movb %dl, -0x509(%rbp)
movq %rax, -0x508(%rbp)
jmp 0x48fd1
movb -0x509(%rbp), %al
movq -0x508(%rbp), %rcx
movq %rcx, -0x400(%rbp)
movb %al, -0x3f8(%rbp)
leaq -0x3e8(%rbp), %rdi
xorl %esi, %esi
callq 0x4a620
movq %rax, -0x408(%rbp)
movq -0x408(%rbp), %rsi
leaq -0x68(%rbp), %rdi
callq 0x4a5e0
movq %rax, -0x520(%rbp)
jmp 0x49019
movq -0x520(%rbp), %rax
movq %rax, -0x410(%rbp)
jmp 0x48f58
movl $0x0, -0x4(%rbp)
movl $0x1, -0x294(%rbp)
leaq -0x270(%rbp), %rdi
callq 0x6140
leaq -0x68(%rbp), %rdi
callq 0x4a650
movl -0x4(%rbp), %eax
movq %rbp, %rsp
popq %rbp
retq
leaq -0x270(%rbp), %rdi
callq 0x6140
leaq -0x68(%rbp), %rdi
callq 0x4a650
movq -0x278(%rbp), %rdi
callq 0x6900
nopl (%rax,%rax)