// File: /workspace/github_cpp_makefile_star2_O2/gersteinlab[P]MUSIC/src/ms_annot_region_tools.cpp
// Function: get_overlap_statistics(std::vector<t_annot_region*, std::allocator<t_annot_region*>>*, std::vector<t_annot_region*, std::allocator<t_annot_region*>>*, std::vector<double, std::allocator<double>>*, std::vector<int, std::allocator<int>>*, double)
void get_overlap_statistics(vector<t_annot_region*>* regs1, vector<t_annot_region*>* regs2, 
							vector<double>* bases, vector<int>* stat_counts, double sim_step)
{
	if(bases->size() == 0)
	{
		fprintf(stderr, "Setting up overlapping bases and counts.\n");
		double cur_sim = 0.0;
		while(cur_sim < 1.0)
		{
			stat_counts->push_back(0);
			bases->push_back(cur_sim);
			cur_sim += sim_step;
		} // sim_step loop.
	}

	t_sorted_annot_region_lists* regs1_res = restructure_annot_regions(regs1);
	t_sorted_annot_region_lists* regs2_res = restructure_annot_regions(regs2);

	for(int i_chr = 0; i_chr < (int)regs1_res->chr_ids->size(); i_chr++)
	{
		vector<t_annot_region*>* cur_reg1_regs = regs1_res->regions_per_chrom[i_chr];
		sort(cur_reg1_regs->begin(), cur_reg1_regs->end());

		// Compare the TARs that are overlapping.
		int i_chr2 = t_string::get_i_str(regs2_res->chr_ids, regs1_res->chr_ids->at(i_chr));

		if(i_chr2 < (int)regs2_res->chr_ids->size())
		{
			vector<t_annot_region*>* cur_reg2_regs = regs2_res->regions_per_chrom[i_chr2];
			sort(cur_reg2_regs->begin(), cur_reg2_regs->end());

			for(int i_reg = 0; i_reg < (int)cur_reg1_regs->size(); i_reg++)
			{
				// Find the region in the region list via binary search.
				int i_posn = locate_posn_region_per_region_starts(cur_reg1_regs->at(i_reg)->start, cur_reg2_regs, 0, cur_reg2_regs->size()-1);

				while(i_posn > 0 && 
					cur_reg2_regs->at(i_posn)->end > cur_reg1_regs->at(i_reg)->start)
				{
					i_posn--;
				}

				int max_l_overlap = 0;
				while(i_posn < (int)cur_reg2_regs->size() &&
					cur_reg2_regs->at(i_posn)->start < cur_reg1_regs->at(i_reg)->end)
				{
					int ol_start = MAX(cur_reg1_regs->at(i_reg)->start, cur_reg2_regs->at(i_posn)->start);
					int ol_end = MIN(cur_reg1_regs->at(i_reg)->end, cur_reg2_regs->at(i_posn)->end);

					if(ol_end > ol_start)
					{
						int l_cur_ol = (ol_end-ol_start+1);
						if(max_l_overlap < l_cur_ol)
						{
							max_l_overlap = l_cur_ol;
						}
					}

					i_posn++;
				} // i_posn loop.

				double ol_fraction = (double)max_l_overlap / (cur_reg1_regs->at(i_reg)->end - cur_reg1_regs->at(i_reg)->start + 1);

				// Get the id for the current overlap fraction.
				int i_ol_fraction = (int)floor((double)ol_fraction / (double)sim_step);

				if(i_ol_fraction == (int)stat_counts->size())
				{
					i_ol_fraction--;
				}

				// Update the count.
				stat_counts->at(i_ol_fraction) = stat_counts->at(i_ol_fraction)+1;
			} // i_reg loop.
		}
		else
		{
			// All of the regions in this chromosome have 0% overlap.
			stat_counts->at(0) = stat_counts->at(0) + (int)regs1_res->chr_ids->size();
		}
	} // i_chr loop.

	// Free memory.
	delete_restructured_annot_regions(regs1_res);
	delete_restructured_annot_regions(regs2_res);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movsd %xmm0, 0x28(%rsp)
movq %rcx, 0x10(%rsp)
movq %rsi, %r14
movq %rdi, %r15
movq 0x8(%rdx), %rax
cmpq (%rdx), %rax
je 0x12b29
movq %r15, %rdi
callq 0x12b99
movq %rax, %rbx
movq %r14, %rdi
callq 0x12b99
movq %rax, %r15
movq %rbx, 0x20(%rsp)
movq 0x18(%rbx), %r12
xorl %ebx, %ebx
movq %rax, 0x40(%rsp)
movq %r12, 0x38(%rsp)
movq 0x8(%r12), %rax
subq (%r12), %rax
shrq $0x3, %rax
cltq
cmpq %rax, %rbx
jge 0x12b08
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%rbx,8), %rbp
movq (%rbp), %rdi
movq 0x8(%rbp), %rsi
callq 0x1817a
movq 0x18(%r15), %r14
movq %r12, %rdi
movq %rbx, 0x48(%rsp)
movq %rbx, %rsi
callq 0x7342
movq (%rax), %rsi
movq %r14, %rdi
callq 0x21152
movq 0x18(%r15), %rcx
movq 0x8(%rcx), %rdx
subq (%rcx), %rdx
shrq $0x3, %rdx
cmpl %edx, %eax
jge 0x12ac7
movq (%r15), %rcx
cltq
movq (%rcx,%rax,8), %r14
movq (%r14), %rdi
movq 0x8(%r14), %rsi
callq 0x1817a
xorl %r15d, %r15d
movq 0x8(%rbp), %rax
subq (%rbp), %rax
shrq $0x3, %rax
cltq
cmpq %rax, %r15
jge 0x12af1
movq %rbp, %rdi
movq %r15, %rsi
callq 0x7404
movq (%rax), %rax
movl 0xc(%rax), %edi
movq 0x8(%r14), %rcx
subq (%r14), %rcx
shrq $0x3, %rcx
decl %ecx
movq %r14, %rsi
xorl %edx, %edx
callq 0x12dee
movl %eax, %r12d
movl %eax, %r13d
sarl $0x1f, %eax
andl %r12d, %eax
movl %eax, 0x8(%rsp)
incl %r12d
testl %r13d, %r13d
jle 0x1293a
movq %r14, %rdi
movq %r13, %rsi
callq 0x7404
movq (%rax), %rax
movl 0x20(%rax), %ebx
movq %rbp, %rdi
movq %r15, %rsi
callq 0x7404
movq (%rax), %rax
decq %r13
decl %r12d
cmpl 0xc(%rax), %ebx
jg 0x12909
jmp 0x1293f
movl 0x8(%rsp), %r12d
movslq %r12d, %r12
xorl %r13d, %r13d
movq %r15, 0x50(%rsp)
movq 0x8(%r14), %rax
subq (%r14), %rax
shrq $0x3, %rax
cltq
cmpq %rax, %r12
jge 0x12a36
movq %r14, %rdi
movq %r12, %rsi
callq 0x7404
movq (%rax), %rax
movl 0xc(%rax), %ebx
movq %rbp, %rdi
movq %r15, %rsi
callq 0x7404
movq (%rax), %rax
cmpl 0x20(%rax), %ebx
jge 0x12a36
movq %rbp, %rdi
movq %r15, %rsi
callq 0x7404
movq (%rax), %rax
movl 0xc(%rax), %ebx
movq %r14, %rdi
movq %r12, %rsi
callq 0x7404
movq (%rax), %rax
cmpl 0xc(%rax), %ebx
movl %r13d, 0x8(%rsp)
jle 0x129b9
movq %rbp, %rdi
movq %r15, %rsi
jmp 0x129bf
movq %r14, %rdi
movq %r12, %rsi
callq 0x7404
movq (%rax), %rax
movl 0xc(%rax), %ebx
movq %rbp, %rdi
movq %r15, %rsi
callq 0x7404
movq (%rax), %rax
movq %r15, %r13
movq %rbp, %r15
movl 0x20(%rax), %ebp
movq %r14, %rdi
movq %r12, %rsi
callq 0x7404
movq (%rax), %rax
cmpl 0x20(%rax), %ebp
jge 0x129fc
movq %r15, %rdi
movq %r13, %rsi
jmp 0x12a02
movq %r14, %rdi
movq %r12, %rsi
callq 0x7404
movq %r15, %rbp
movq (%rax), %rax
movl 0x20(%rax), %eax
movl %eax, %ecx
subl %ebx, %ecx
movl 0x8(%rsp), %r13d
cmpl %ecx, %r13d
leal 0x1(%rcx), %ecx
cmovgl %r13d, %ecx
cmpl %ebx, %eax
cmovgl %ecx, %r13d
incq %r12
movq 0x50(%rsp), %r15
jmp 0x1294a
cvtsi2sd %r13d, %xmm0
movsd %xmm0, 0x8(%rsp)
movq %rbp, %rdi
movq %r15, %rsi
callq 0x7404
movq (%rax), %rax
movl 0x20(%rax), %ebx
movq %rbp, %rdi
movq %r15, %rsi
callq 0x7404
movq (%rax), %rax
subl 0xc(%rax), %ebx
incl %ebx
cvtsi2sd %ebx, %xmm0
movsd 0x8(%rsp), %xmm1
divsd %xmm0, %xmm1
divsd 0x28(%rsp), %xmm1
movapd %xmm1, %xmm0
callq 0x22b0
cvttsd2si %xmm0, %eax
movq 0x10(%rsp), %r13
movq 0x8(%r13), %rcx
subq (%r13), %rcx
shrq $0x2, %rcx
xorl %edx, %edx
cmpl %ecx, %eax
sete %dl
subl %edx, %eax
movslq %eax, %r12
movq %r13, %rdi
movq %r12, %rsi
callq 0x7364
movl (%rax), %ebx
incl %ebx
movq %r13, %rdi
movq %r12, %rsi
callq 0x7364
movl %ebx, (%rax)
incq %r15
jmp 0x128b7
movq 0x10(%rsp), %r14
movq %r14, %rdi
xorl %esi, %esi
callq 0x7364
movq 0x8(%r12), %rbx
subq (%r12), %rbx
shrq $0x3, %rbx
addl (%rax), %ebx
movq %r14, %rdi
xorl %esi, %esi
callq 0x7364
movl %ebx, (%rax)
movq 0x48(%rsp), %rbx
incq %rbx
movq 0x40(%rsp), %r15
movq 0x38(%rsp), %r12
jmp 0x12838
movq 0x20(%rsp), %rdi
callq 0x12f32
movq %r15, %rdi
callq 0x12f32
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rdx, %r12
movq 0x224ad(%rip), %rax     # 0x34fe0
movq (%rax), %rcx
leaq 0x14dcf(%rip), %rdi     # 0x2790c
pushq $0x29
popq %rsi
pushq $0x1
popq %rdx
callq 0x2330
xorpd %xmm0, %xmm0
leaq 0x1c(%rsp), %r13
leaq 0x30(%rsp), %rbp
movsd %xmm0, 0x30(%rsp)
movsd 0x114a4(%rip), %xmm1    # 0x24008
ucomisd %xmm0, %xmm1
jbe 0x1280d
andl $0x0, 0x1c(%rsp)
movq 0x10(%rsp), %rdi
movq %r13, %rsi
callq 0x77a4
movq %r12, %rdi
movq %rbp, %rsi
callq 0x7426
movsd 0x30(%rsp), %xmm0
addsd 0x28(%rsp), %xmm0
jmp 0x12b56