// File: /workspace/github_cpp_makefile_star2_O3/gersteinlab[P]MUSIC/src/ms_signal_enrichment_utils.cpp
// Function: filter_regions_per_window_average(std::vector<t_annot_region*, std::allocator<t_annot_region*>>*, double*, int, double*, int, double, int)
vector<t_annot_region*>* filter_regions_per_window_average(vector<t_annot_region*>* regions, 
	double* signal_profile, int l_profile, double* control_profile, int l_control,
	double fdr, int l_win)
{
	// Go over all the windows.
	int cur_win_start = 0;
	int cur_l_win = l_win;

	// Sort the regions.
	sort(regions->begin(), regions->end(), sort_regions);

	// List of pruned regions.
	vector<t_annot_region*>* pruned_regions = new vector<t_annot_region*>();

	// The windowing schedule matches up with the ms_decomposition.
	while(cur_win_start < l_profile)
	{
		// Set the length of the window 
		if(cur_win_start+l_win > l_profile)
		{
			cur_l_win = l_profile - cur_win_start;
		}
		else
		{
			cur_l_win = l_win;
		}

		//fprintf(stderr, "Processing %d-%d\n", cur_win_start, cur_win_start+cur_l_win);

		// Get the minimum and maximum in the window.
		int max_thresh = 0;
		for(int i = cur_win_start; i < cur_win_start+cur_l_win && i < l_profile; i++)
		{
			if(max_thresh < signal_profile[i])
			{
				max_thresh = (int)(signal_profile[i]);
			}
		} // i loop.


//#define __POISSON_BCKGRND__
//#undef __GEOMETRIC_BCKGRND__
#ifdef __POISSON_BCKGRND__
		double cur_win_thresh = get_poisson_thresholds_per_win(signal_profile,
										l_profile,
										cur_l_win,
										cur_win_start,
										fdr,
										1,
										max_thresh);
#elif defined __GEOMETRIC_BCKGRND__
		double cur_win_thresh = get_geometric_thresholds_per_win(signal_profile,
										l_profile,
										cur_l_win,
										cur_win_start,
										fdr,
										1,
										max_thresh);
#else
		#error "Did not select a background model."
#endif // Bckgrnd selection

		//fprintf(stderr, "Window: %d-%d: Threshold: %lf\n", cur_win_start, cur_win_start + cur_l_win, cur_win_thresh);

		// Go over all the regions in the current window and prune the ends with respect to the threshold.
		vector<double>* cur_region_sigs = new vector<double>();

		// Go over all the regions in the current window and prune the ends with respect to the threshold.
		for(int i_reg = 0; cur_win_thresh > 0 && i_reg < (int)regions->size(); i_reg++)
		{
			// Process the current region if its start is in the current window.
			if((regions->at(i_reg)->start >= cur_win_start &&
				regions->at(i_reg)->start < cur_win_start + cur_l_win))
			{
				// Get the median signal value in the current region.
				for(int i = regions->at(i_reg)->start; i <= regions->at(i_reg)->end; i++)
				{
					cur_region_sigs->push_back(signal_profile[i]);
				} // i loop.

				sort(cur_region_sigs->begin(), cur_region_sigs->end());

				if(cur_region_sigs->at(cur_region_sigs->size() / 2) > cur_win_thresh)
				{
					pruned_regions->push_back(duplicate_region(regions->at(i_reg)));
				}

				cur_region_sigs->clear();
			} // check if the current region is in the current window.
		} // i_reg loop.

		delete cur_region_sigs;

		// Update window.
		cur_win_start += l_win;
	} // window start check.

if(__DUMP_SIGNAL_ENRICHMENT_MSGS__)
	fprintf(stderr, "Pruned to %d (%d) regions.\n", (int)regions->size(), (int)pruned_regions->size());

	return(pruned_regions);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %r9d, 0x28(%rsp)
movsd %xmm0, 0x48(%rsp)
movl %edx, %ebp
movq %rsi, 0x38(%rsp)
movq %rdi, %rbx
movq (%rdi), %r15
movq 0x8(%rdi), %r12
cmpq %r12, %r15
movl %edx, 0xc(%rsp)
je 0x1f5e5
movq %r12, %r14
subq %r15, %r14
movq %r14, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x8545(%rip), %rcx     # 0x16f04
movq %r15, %rdi
movq %r12, %rsi
callq 0x1c455
leaq 0x8(%r15), %rax
cmpq $0x81, %r14
movq %r12, 0x10(%rsp)
jl 0x1f566
movl $0x8, %r13d
movq %rax, 0x18(%rsp)
movq %rax, %r14
movq %r15, 0x20(%rsp)
movq %r15, %r12
movq %r12, 0x30(%rsp)
movq 0x20(%rsp), %r15
leaq (%r15,%r13), %r12
movq (%r15,%r13), %rdi
movq (%r15), %rsi
callq 0x16f04
movq (%r15,%r13), %rbp
testb %al, %al
je 0x1f4b4
movq 0x18(%rsp), %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0x22b0
jmp 0x1f4ec
movq 0x30(%rsp), %rax
movq (%rax), %rsi
movq %rbp, %rdi
callq 0x16f04
movq %r12, %r15
testb %al, %al
je 0x1f4ec
movq %r14, %rcx
leaq -0x8(%rcx), %r15
movq -0x10(%rcx), %rsi
movq -0x8(%rcx), %rax
movq %rax, (%rcx)
movq %rbp, %rdi
callq 0x16f04
movq %r15, %rcx
testb %al, %al
jne 0x1f4ce
movq %rbp, (%r15)
addq $0x8, %r13
addq $0x8, %r14
cmpq $0x80, %r13
jne 0x1f480
movq 0x20(%rsp), %r15
subq $-0x80, %r15
cmpq 0x10(%rsp), %r15
movl 0xc(%rsp), %ebp
je 0x1f5e5
movl 0xc(%rsp), %ebp
movq -0x8(%r15), %rsi
movq (%r15), %r14
movq %r14, %rdi
callq 0x16f04
movq %r15, %r12
testb %al, %al
je 0x1f553
movq %r12, %rcx
leaq -0x8(%rcx), %r15
movq -0x10(%rcx), %rsi
movq -0x8(%rcx), %rax
movq %rax, (%rcx)
movq %r14, %rdi
callq 0x16f04
movq %r15, %rcx
testb %al, %al
jne 0x1f535
movq %r14, (%r15)
movq %r12, %r15
addq $0x8, %r15
cmpq 0x10(%rsp), %r15
jne 0x1f51c
jmp 0x1f5e5
cmpq %r12, %rax
je 0x1f5e5
movq %r15, %r13
movq %r13, %r14
movq %rax, %r13
movq (%rax), %rdi
movq (%r15), %rsi
callq 0x16f04
movq (%r13), %r12
testb %al, %al
je 0x1f5a4
movq %r13, %rdx
subq %r15, %rdx
subq %rdx, %r14
addq $0x10, %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x22b0
movq %r15, %r14
jmp 0x1f5d7
movq (%r14), %rsi
movq %r12, %rdi
callq 0x16f04
movq %r13, %r14
testb %al, %al
je 0x1f5d7
movq %r13, %rcx
leaq -0x8(%rcx), %r14
movq -0x10(%rcx), %rsi
movq -0x8(%rcx), %rax
movq %rax, (%rcx)
movq %r12, %rdi
callq 0x16f04
movq %r14, %rcx
testb %al, %al
jne 0x1f5b9
movq %r12, (%r14)
leaq 0x8(%r13), %rax
cmpq 0x10(%rsp), %rax
jne 0x1f56e
movl $0x18, %edi
callq 0x2180
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq %rax, 0x18(%rsp)
movq $0x0, 0x10(%rax)
testl %ebp, %ebp
movq 0x38(%rsp), %r14
jle 0x1f89c
movslq 0x28(%rsp), %r15
xorl %r13d, %r13d
movq %r15, 0x40(%rsp)
leaq (%r15,%r13), %rax
movl %ebp, %edx
subl %r13d, %edx
movq %rax, 0x28(%rsp)
cmpl %ebp, %eax
cmovlel %r15d, %edx
leal (%rdx,%r13), %ecx
cmpl %ebp, %ecx
movl %ebp, %eax
movl %ecx, 0x30(%rsp)
cmovll %ecx, %eax
movl $0x0, %r9d
cmpl %r13d, %eax
jle 0x1f678
cltq
xorl %esi, %esi
movq %r13, %rcx
xorps %xmm0, %xmm0
cvtsi2sd %esi, %xmm0
movsd (%r14,%rcx,8), %xmm1
ucomisd %xmm0, %xmm1
cvttsd2si %xmm1, %r9d
cmovbel %esi, %r9d
incq %rcx
movl %r9d, %esi
cmpq %rax, %rcx
jl 0x1f653
movq %r14, %rdi
movl %ebp, %esi
movl %r13d, %ecx
movsd 0x48(%rsp), %xmm0
movl $0x1, %r8d
callq 0x1de93
movsd %xmm0, 0x10(%rsp)
movl $0x18, %edi
callq 0x2180
movq %rax, %r12
movsd 0x10(%rsp), %xmm0
ucomisd 0xa9fe(%rip), %xmm0     # 0x2a0b0
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq $0x0, 0x10(%rax)
jbe 0x1f881
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
movq %rcx, %rdx
subq %rax, %rdx
movq %rdx, %rsi
shlq $0x1d, %rsi
movabsq $0x100000000, %rdi      # imm = 0x100000000
cmpq %rdi, %rsi
jl 0x1f864
xorl %r15d, %r15d
xorl %edi, %edi
movq %r13, 0x20(%rsp)
sarq $0x3, %rdx
cmpq %r15, %rdx
jbe 0x1f8cc
movq (%rax,%r15,8), %rdx
movl 0xc(%rdx), %edx
cmpl %r13d, %edx
jl 0x1f83f
cmpl 0x30(%rsp), %edx
jge 0x1f83f
movslq %edx, %r13
leaq (%r14,%r13,8), %rbp
movq (%rax,%r15,8), %rdx
movslq 0x20(%rdx), %rdx
movq 0x8(%r12), %r14
cmpq %rdx, %r13
jg 0x1f785
cmpq 0x10(%r12), %r14
je 0x1f755
movsd (%rbp), %xmm0
movsd %xmm0, (%r14)
addq $0x8, %r14
movq %r14, 0x8(%r12)
jmp 0x1f76a
movq %r12, %rdi
movq %r14, %rsi
movq %rbp, %rdx
callq 0xb60c
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
incq %r13
movq %rcx, %rdx
subq %rax, %rdx
sarq $0x3, %rdx
addq $0x8, %rbp
cmpq %r15, %rdx
ja 0x1f727
jmp 0x1f8cc
movq (%r12), %rbp
cmpq %r14, %rbp
je 0x1f8dd
movq %r14, %rax
subq %rbp, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %rbp, %rdi
movq %r14, %rsi
callq 0x21573
movq %rbp, %rdi
movq %r14, %rsi
callq 0x2166c
movq (%r12), %rdi
movq 0x8(%r12), %rax
movq %rax, %rdx
subq %rdi, %rdx
sarq $0x3, %rdx
movq %rdx, %rsi
shrq %rsi
cmpq %rdi, %rax
movq 0x20(%rsp), %r13
je 0x1f8e1
movsd (%rdi,%rsi,8), %xmm0
ucomisd 0x10(%rsp), %xmm0
movq 0x38(%rsp), %r14
jbe 0x1f835
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %r15, %rdx
jbe 0x1f8cc
movq (%rax,%r15,8), %rdi
callq 0x16f1f
movq %rax, 0x50(%rsp)
movq 0x18(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x108ac
movq (%r12), %rdi
movq 0x8(%r12), %rax
cmpq %rdi, %rax
je 0x1f83f
movq %rdi, 0x8(%r12)
incq %r15
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
movq %rcx, %rdx
subq %rax, %rdx
movq %rdx, %rsi
shrq $0x3, %rsi
movslq %esi, %rsi
cmpq %rsi, %r15
jl 0x1f6f9
jmp 0x1f866
xorl %edi, %edi
testq %rdi, %rdi
movl 0xc(%rsp), %ebp
movq 0x40(%rsp), %r15
je 0x1f881
movq 0x10(%r12), %rsi
subq %rdi, %rsi
callq 0x2190
movl $0x18, %esi
movq %r12, %rdi
callq 0x2190
movq 0x28(%rsp), %r13
cmpl %ebp, %r13d
jl 0x1f61e
cmpb $0x1, 0x1992d(%rip)     # 0x391d0
je 0x1f8b9
movq 0x18(%rsp), %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x8(%rbx), %rdi
movq %rbx, %rsi
movq 0x18(%rsp), %rdx
callq 0x50e4
jmp 0x1f8a5
leaq 0xcffd(%rip), %rdi      # 0x2c8d0
movq %r15, %rsi
xorl %eax, %eax
callq 0x2270
xorl %esi, %esi
xorl %edx, %edx
leaq 0xcfe8(%rip), %rdi      # 0x2c8d0
jmp 0x1f8d6