// File: CK7[P]abawaca/src/abawaca-build.cpp
// Function: Scaf_segment::Scaf_segment(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned long, unsigned long, Bio::DNAString const&)
Scaf_segment::Scaf_segment(string _display_id, string _desc, size_t s, size_t e, const Bio::DNAString& _seq) : start(s), end(e), Sequence(_display_id, _seq), desc(_desc)
{
	int k = 4;
	if(dimension2index.size() == 0) {
		prepare_mer_indexes(k, dimension2index);
	}
	dimensions.resize(dimension_order.size());

	// Compute 1,2,3 and 4-mer frequencies
	int factor = 10;
	int N_limit = 1;
	for(auto i=1; i<=k; i++, N_limit*=10, factor*=10) {
		// Shouldn't happen...
		if(seq.size() < i)
			continue;

		unordered_map<size_t, size_t>	counts;
		int 	key=0, total=0;
		auto	it_start = seq.begin(), it_end = seq.begin();

		// Add first mer
		while(it_end-it_start < i) {
			key *= 10;	// 0=00000, 2=00010, 6=00110, 19=10011
			switch(*(it_end++)) {
				case 'A':	key += 2;	break;
				case 'C':	key += 3;	break;
				case 'G':	key += 4;	break;
				case 'T':	key += 5;	break;
				default:	key = 0;
			}
		}
		if(key > N_limit) {
			counts[key]++;
 			total++;
		}
		// Rest of the mers
		while(it_end != seq.end()) {
			key *= 10;
			key = key%factor;
			switch(*(it_end++)) {
				case 'A':	key += 2;	break;
				case 'C':	key += 3;	break;
				case 'G':	key += 4;	break;
				case 'T':	key += 5;	break;
				default:	key = 0;
			}

			// The following means that there are no N's in mer)
			if(key > N_limit) {
				counts[key]++;
				total++;
			}
		}

		for(auto it=counts.begin(); it!=counts.end(); it++) {
			string mer;
			for(int i=factor; i>0; i/=10)
			switch((it->first/i)%10) {
				case 2:	mer.push_back('A');	break;
				case 3:	mer.push_back('C');	break;
				case 4:	mer.push_back('G');	break;
				case 5:	mer.push_back('T');	break;
			}
			auto sit = dimension2index.find(mer);
			if(sit == dimension2index.end()) {
				cerr << "Error: could not find index for " << mer << endl;
				exit(-1);
			}
			dimensions[sit->second] += (total != 0)? (double(it->second)/total): 0;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1f0, %rsp            # imm = 0x1F0
movq %rdx, -0x150(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x148(%rbp)
leaq -0x50(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq 0x4140
movq -0x148(%rbp), %rdi
movq -0x140(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x10220
jmp 0xb2ae
leaq -0x50(%rbp), %rdi
callq 0x41c0
movq -0x148(%rbp), %rdi
movq -0x150(%rbp), %rsi
leaq 0x267ec(%rip), %rax     # 0x31ab8
movq %rax, (%rdi)
movq -0x20(%rbp), %rax
movq %rax, 0x48(%rdi)
movq -0x28(%rbp), %rax
movq %rax, 0x50(%rdi)
addq $0x58, %rdi
movq %rdi, -0x158(%rbp)
callq 0x4140
jmp 0xb2f1
movq -0x148(%rbp), %rdi
addq $0x78, %rdi
movq %rdi, -0x160(%rbp)
callq 0x10290
movl $0x4, -0x60(%rbp)
leaq 0x2709a(%rip), %rdi     # 0x323b0
callq 0x102b0
cmpq $0x0, %rax
jne 0xb370
movl -0x60(%rbp), %edi
leaq 0x27085(%rip), %rsi     # 0x323b0
callq 0xb190
jmp 0xb332
jmp 0xb370
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x41c0
jmp 0xba3a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0xba2e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0xba16
movq -0x148(%rbp), %rax
addq $0x78, %rax
movq %rax, -0x168(%rbp)
leaq 0x27057(%rip), %rdi     # 0x323e0
callq 0x6640
movq -0x168(%rbp), %rdi
movq %rax, %rsi
callq 0x102d0
jmp 0xb39f
movl $0xa, -0x64(%rbp)
movl $0x1, -0x68(%rbp)
movl $0x1, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
cmpl -0x60(%rbp), %eax
jg 0xba0d
movq -0x148(%rbp), %rdi
addq $0x28, %rdi
callq 0x7020
movq %rax, -0x170(%rbp)
jmp 0xb3d9
movq -0x170(%rbp), %rax
movslq -0x6c(%rbp), %rcx
cmpq %rcx, %rax
jae 0xb3ee
jmp 0xb9e3
leaq -0xa8(%rbp), %rdi
callq 0x10360
movq -0x148(%rbp), %rdi
movl $0x0, -0xac(%rbp)
movl $0x0, -0xb0(%rbp)
addq $0x28, %rdi
callq 0x10380
movq %rax, -0x178(%rbp)
jmp 0xb427
movq -0x148(%rbp), %rdi
movq -0x178(%rbp), %rax
movq %rax, -0xb8(%rbp)
addq $0x28, %rdi
callq 0x10380
movq %rax, -0x180(%rbp)
jmp 0xb44e
movq -0x180(%rbp), %rax
movq %rax, -0xc0(%rbp)
leaq -0xc0(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x103b0
movslq -0x6c(%rbp), %rcx
cmpq %rcx, %rax
jge 0xb53f
movl -0xac(%rbp), %ecx
addl %ecx, %ecx
movl %ecx, %eax
leal (%rax,%rax,4), %eax
movl %eax, -0xac(%rbp)
leaq -0xc0(%rbp), %rdi
xorl %esi, %esi
callq 0x103f0
movq %rax, -0xc8(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x8040
movsbl (%rax), %eax
addl $-0x41, %eax
movl %eax, %ecx
movq %rcx, -0x188(%rbp)
subl $0x13, %eax
ja 0xb530
movq -0x188(%rbp), %rax
leaq 0x170a6(%rip), %rcx     # 0x22578
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0xb9ff
movl -0xac(%rbp), %eax
addl $0x2, %eax
movl %eax, -0xac(%rbp)
jmp 0xb53a
movl -0xac(%rbp), %eax
addl $0x3, %eax
movl %eax, -0xac(%rbp)
jmp 0xb53a
movl -0xac(%rbp), %eax
addl $0x4, %eax
movl %eax, -0xac(%rbp)
jmp 0xb53a
movl -0xac(%rbp), %eax
addl $0x5, %eax
movl %eax, -0xac(%rbp)
jmp 0xb53a
movl $0x0, -0xac(%rbp)
jmp 0xb45c
movl -0xac(%rbp), %eax
cmpl -0x68(%rbp), %eax
jle 0xb594
movslq -0xac(%rbp), %rax
movq %rax, -0xd0(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x10430
movq %rax, -0x190(%rbp)
jmp 0xb574
movq -0x190(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movl -0xb0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb0(%rbp)
jmp 0xb596
movq -0x148(%rbp), %rdi
addq $0x28, %rdi
callq 0x104a0
movq %rax, -0x198(%rbp)
jmp 0xb5af
movq -0x198(%rbp), %rax
movq %rax, -0xd8(%rbp)
leaq -0xc0(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x10460
testb $0x1, %al
jne 0xb5d9
jmp 0xb6f2
movl -0xac(%rbp), %ecx
addl %ecx, %ecx
movl %ecx, %eax
leal (%rax,%rax,4), %eax
movl %eax, -0xac(%rbp)
movl -0xac(%rbp), %eax
movl -0x64(%rbp), %ecx
cltd
idivl %ecx
movl %edx, -0xac(%rbp)
leaq -0xc0(%rbp), %rdi
xorl %esi, %esi
callq 0x103f0
movq %rax, -0xe0(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x8040
movsbl (%rax), %eax
addl $-0x41, %eax
movl %eax, %ecx
movq %rcx, -0x1a0(%rbp)
subl $0x13, %eax
ja 0xb68e
movq -0x1a0(%rbp), %rax
leaq 0x16ee7(%rip), %rcx     # 0x22528
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl -0xac(%rbp), %eax
addl $0x2, %eax
movl %eax, -0xac(%rbp)
jmp 0xb698
movl -0xac(%rbp), %eax
addl $0x3, %eax
movl %eax, -0xac(%rbp)
jmp 0xb698
movl -0xac(%rbp), %eax
addl $0x4, %eax
movl %eax, -0xac(%rbp)
jmp 0xb698
movl -0xac(%rbp), %eax
addl $0x5, %eax
movl %eax, -0xac(%rbp)
jmp 0xb698
movl $0x0, -0xac(%rbp)
movl -0xac(%rbp), %eax
cmpl -0x68(%rbp), %eax
jle 0xb6ed
movslq -0xac(%rbp), %rax
movq %rax, -0xe8(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x10430
movq %rax, -0x1a8(%rbp)
jmp 0xb6cd
movq -0x1a8(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movl -0xb0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb0(%rbp)
jmp 0xb596
leaq -0xa8(%rbp), %rdi
callq 0x104d0
movq %rax, -0xf0(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x10530
movq %rax, -0xf8(%rbp)
leaq -0xf0(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x10500
testb $0x1, %al
jne 0xb734
jmp 0xb9d7
leaq -0x118(%rbp), %rdi
callq 0x4490
movl -0x64(%rbp), %eax
movl %eax, -0x11c(%rbp)
cmpl $0x0, -0x11c(%rbp)
jle 0xb857
leaq -0xf0(%rbp), %rdi
callq 0x10560
movq (%rax), %rax
movslq -0x11c(%rbp), %rcx
xorl %edx, %edx
divq %rcx
movq %rax, -0x1b8(%rbp)
movabsq $-0x3333333333333333, %rcx # imm = 0xCCCCCCCCCCCCCCCD
mulq %rcx
movq -0x1b8(%rbp), %rax
movq %rdx, %rcx
shrq $0x2, %rcx
andq $-0x2, %rcx
leaq (%rcx,%rcx,4), %rcx
negq %rcx
leaq -0x2(%rax,%rcx), %rax
movq %rax, -0x1b0(%rbp)
subq $0x3, %rax
ja 0xb83c
movq -0x1b0(%rbp), %rax
leaq 0x16d56(%rip), %rcx     # 0x22518
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq -0x118(%rbp), %rdi
movl $0x41, %esi
callq 0x4260
jmp 0xb7de
jmp 0xb83c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x41c0
jmp 0xb9ff
leaq -0x118(%rbp), %rdi
movl $0x43, %esi
callq 0x4260
jmp 0xb810
jmp 0xb83c
leaq -0x118(%rbp), %rdi
movl $0x47, %esi
callq 0x4260
jmp 0xb825
jmp 0xb83c
leaq -0x118(%rbp), %rdi
movl $0x54, %esi
callq 0x4260
jmp 0xb83a
jmp 0xb83c
jmp 0xb83e
movl -0x11c(%rbp), %eax
movl $0xa, %ecx
cltd
idivl %ecx
movl %eax, -0x11c(%rbp)
jmp 0xb749
leaq 0x26b52(%rip), %rdi     # 0x323b0
leaq -0x118(%rbp), %rsi
callq 0xff70
movq %rax, -0x1c0(%rbp)
jmp 0xb873
movq -0x1c0(%rbp), %rax
movq %rax, -0x128(%rbp)
leaq 0x26b28(%rip), %rdi     # 0x323b0
callq 0x10000
movq %rax, -0x130(%rbp)
leaq -0x128(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0xffd0
testb $0x1, %al
jne 0xb8ad
jmp 0xb904
movq 0x2673c(%rip), %rdi     # 0x31ff0
leaq 0x16d5b(%rip), %rsi     # 0x22616
callq 0x42f0
movq %rax, -0x1c8(%rbp)
jmp 0xb8c9
movq -0x1c8(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x4290
movq %rax, -0x1d0(%rbp)
jmp 0xb8e5
movq -0x1d0(%rbp), %rdi
movq 0x266c5(%rip), %rsi     # 0x31fb8
callq 0x4340
jmp 0xb8fa
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x43f0
cmpl $0x0, -0xb0(%rbp)
je 0xb956
leaq -0xf0(%rbp), %rdi
callq 0x10560
movq 0x8(%rax), %xmm0
movaps 0x169ab(%rip), %xmm1    # 0x222d0
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x169af(%rip), %xmm1    # 0x222e0
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
cvtsi2sdl -0xb0(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x1d8(%rbp)
jmp 0xb963
xorps %xmm0, %xmm0
movsd %xmm0, -0x1d8(%rbp)
jmp 0xb963
movq -0x148(%rbp), %rax
movsd -0x1d8(%rbp), %xmm0
movsd %xmm0, -0x1e0(%rbp)
addq $0x78, %rax
movq %rax, -0x1e8(%rbp)
leaq -0x128(%rbp), %rdi
callq 0x10140
movq -0x1e8(%rbp), %rdi
movq 0x20(%rax), %rsi
callq 0x10590
movsd -0x1e0(%rbp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
leaq -0x118(%rbp), %rdi
callq 0x41c0
leaq -0xf0(%rbp), %rdi
xorl %esi, %esi
callq 0x105b0
movq %rax, -0x138(%rbp)
jmp 0xb705
leaq -0xa8(%rbp), %rdi
callq 0x105e0
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
imull $0xa, -0x68(%rbp), %eax
movl %eax, -0x68(%rbp)
imull $0xa, -0x64(%rbp), %eax
movl %eax, -0x64(%rbp)
jmp 0xb3b4
leaq -0xa8(%rbp), %rdi
callq 0x105e0
jmp 0xba16
addq $0x1f0, %rsp            # imm = 0x1F0
popq %rbp
retq
movq -0x160(%rbp), %rdi
callq 0x10600
movq -0x158(%rbp), %rdi
callq 0x41c0
movq -0x148(%rbp), %rdi
callq 0x130e0
movq -0x58(%rbp), %rdi
callq 0x45c0
nopw %cs:(%rax,%rax)