// File: /workspace/github_cpp_makefile_star2_O1/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 $0x48, %rsp
movl %r9d, 0x18(%rsp)
movsd %xmm0, 0x38(%rsp)
movl %edx, %ebp
movq %rsi, %r15
movq %rdi, %rbx
movq (%rdi), %r13
movq 0x8(%rdi), %r12
cmpq %r12, %r13
movl %edx, 0x14(%rsp)
movq %rsi, 0x28(%rsp)
je 0x1fa47
movq %r12, %r14
subq %r13, %r14
movq %r14, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x8613(%rip), %rcx     # 0x17291
movq %r13, %rdi
movq %r12, %rsi
callq 0x1c869
movq %r13, %rcx
leaq 0x8(%r13), %rax
cmpq $0x81, %r14
movq %r13, (%rsp)
movq %r12, 0x8(%rsp)
jl 0x1f9c3
movl $0x8, %r13d
movq %rax, 0x20(%rsp)
movq %rax, %r14
movq %rcx, %r12
movq %r12, 0x30(%rsp)
movq (%rsp), %r15
leaq (%r15,%r13), %r12
movq (%r15,%r13), %rdi
movq (%r15), %rsi
callq 0x17291
movq (%r15,%r13), %rbp
testb %al, %al
je 0x1f910
movq 0x20(%rsp), %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0x22b0
jmp 0x1f948
movq 0x30(%rsp), %rax
movq (%rax), %rsi
movq %rbp, %rdi
callq 0x17291
movq %r12, %r15
testb %al, %al
je 0x1f948
movq %r14, %rcx
leaq -0x8(%rcx), %r15
movq -0x10(%rcx), %rsi
movq -0x8(%rcx), %rax
movq %rax, (%rcx)
movq %rbp, %rdi
callq 0x17291
movq %r15, %rcx
testb %al, %al
jne 0x1f92a
movq %rbp, (%r15)
addq $0x8, %r13
addq $0x8, %r14
cmpq $0x80, %r13
jne 0x1f8dd
movq (%rsp), %r13
subq $-0x80, %r13
cmpq 0x8(%rsp), %r13
movl 0x14(%rsp), %ebp
movq 0x28(%rsp), %r15
je 0x1fa47
movq -0x8(%r13), %rsi
movq (%r13), %r12
movq %r12, %rdi
callq 0x17291
movq %r13, %r14
testb %al, %al
je 0x1f9b0
movq %r13, %rcx
leaq -0x8(%rcx), %r14
movq -0x10(%rcx), %rsi
movq -0x8(%rcx), %rax
movq %rax, (%rcx)
movq %r12, %rdi
callq 0x17291
movq %r14, %rcx
testb %al, %al
jne 0x1f992
movq %r12, (%r14)
addq $0x8, %r13
cmpq 0x8(%rsp), %r13
jne 0x1f978
jmp 0x1fa47
cmpq %r12, %rax
je 0x1fa47
movq %rcx, %r13
movq %r13, %r14
movq %rax, %r13
movq (%rax), %rdi
movq (%rcx), %rsi
callq 0x17291
movq (%r13), %r12
testb %al, %al
je 0x1fa02
movq %r13, %rdx
movq (%rsp), %rsi
subq %rsi, %rdx
subq %rdx, %r14
addq $0x10, %r14
movq %r14, %rdi
movq %rsi, %r14
callq 0x22b0
jmp 0x1fa35
movq (%r14), %rsi
movq %r12, %rdi
callq 0x17291
movq %r13, %r14
testb %al, %al
je 0x1fa35
movq %r13, %rcx
leaq -0x8(%rcx), %r14
movq -0x10(%rcx), %rsi
movq -0x8(%rcx), %rax
movq %rax, (%rcx)
movq %r12, %rdi
callq 0x17291
movq %r14, %rcx
testb %al, %al
jne 0x1fa17
movq %r12, (%r14)
leaq 0x8(%r13), %rax
cmpq 0x8(%rsp), %rax
movq (%rsp), %rcx
jne 0x1f9cb
movl $0x18, %edi
callq 0x2180
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq %rax, 0x8(%rsp)
movq $0x0, 0x10(%rax)
testl %ebp, %ebp
jle 0x1fce7
movslq 0x18(%rsp), %rax
movq %rax, 0x18(%rsp)
xorl %r13d, %r13d
movq 0x18(%rsp), %rax
leaq (%rax,%r13), %rcx
movl %ebp, %edx
subl %r13d, %edx
movq %rcx, 0x20(%rsp)
cmpl %ebp, %ecx
cmovlel %eax, %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 0x1fad9
cltq
xorl %esi, %esi
movq %r13, %rcx
xorps %xmm0, %xmm0
cvtsi2sd %esi, %xmm0
movsd (%r15,%rcx,8), %xmm1
ucomisd %xmm0, %xmm1
cvttsd2si %xmm1, %r9d
cmovbel %esi, %r9d
incq %rcx
movl %r9d, %esi
cmpq %rax, %rcx
jl 0x1fab4
movq %r15, %rdi
movl %ebp, %esi
movl %r13d, %ecx
movsd 0x38(%rsp), %xmm0
movl $0x1, %r8d
callq 0x1e321
movsd %xmm0, (%rsp)
movl $0x18, %edi
callq 0x2180
movq %rax, %r12
movsd (%rsp), %xmm0
ucomisd 0xb59f(%rip), %xmm0     # 0x2b0b0
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq $0x0, 0x10(%rax)
jbe 0x1fcab
xorl %r15d, %r15d
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
subq %rax, %rdx
movq %rdx, %rcx
shrq $0x3, %rcx
movslq %ecx, %rcx
cmpq %rcx, %r15
jge 0x1fcab
sarq $0x3, %rdx
cmpq %r15, %rdx
jbe 0x1fd17
movq (%rax,%r15,8), %rax
movl 0xc(%rax), %ecx
cmpl %r13d, %ecx
jl 0x1fc95
cmpl 0x30(%rsp), %ecx
jge 0x1fc95
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %r15, %rdx
jbe 0x1fd17
movslq %ecx, %r14
movq 0x28(%rsp), %rcx
leaq (%rcx,%r14,8), %rbp
movq (%rax,%r15,8), %rax
movslq 0x20(%rax), %rax
cmpq %rax, %r14
jg 0x1fbe8
movq 0x8(%r12), %rsi
cmpq 0x10(%r12), %rsi
je 0x1fbbe
movsd (%rbp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x8(%r12)
jmp 0x1fbc9
movq %r12, %rdi
movq %rbp, %rdx
callq 0xb836
incq %r14
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
addq $0x8, %rbp
cmpq %r15, %rdx
ja 0x1fb91
jmp 0x1fd17
movq (%r12), %rbp
movq 0x8(%r12), %r14
cmpq %r14, %rbp
je 0x1fc23
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 0x21aa4
movq %rbp, %rdi
movq %r14, %rsi
callq 0x21b9d
movq (%r12), %rax
movq 0x8(%r12), %rcx
movq %rcx, %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movq %rdx, %rsi
shrq %rsi
cmpq %rax, %rcx
je 0x1fd28
movsd (%rax,%rsi,8), %xmm0
ucomisd (%rsp), %xmm0
jbe 0x1fc85
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %r15, %rdx
jbe 0x1fd17
movq (%rax,%r15,8), %rdi
callq 0x172ac
movq %rax, 0x40(%rsp)
movq 0x8(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x10b7e
movq (%r12), %rax
cmpq %rax, 0x8(%r12)
je 0x1fc95
movq %rax, 0x8(%r12)
incq %r15
movsd (%rsp), %xmm0
ucomisd 0xb40b(%rip), %xmm0     # 0x2b0b0
ja 0x1fb2a
movq (%r12), %rdi
testq %rdi, %rdi
je 0x1fcc1
movq 0x10(%r12), %rsi
subq %rdi, %rsi
callq 0x2190
movl $0x18, %esi
movq %r12, %rdi
callq 0x2190
movq 0x20(%rsp), %rax
movq %rax, %r13
movl 0x14(%rsp), %ebp
cmpl %ebp, %eax
movq 0x28(%rsp), %r15
jl 0x1fa7b
cmpb $0x1, 0x1a4e2(%rip)     # 0x3a1d0
je 0x1fd04
movq 0x8(%rsp), %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x8(%rbx), %rdi
movq %rbx, %rsi
movq 0x8(%rsp), %rdx
callq 0x5247
jmp 0x1fcf0
leaq 0xdbb8(%rip), %rdi      # 0x2d8d6
movq %r15, %rsi
xorl %eax, %eax
callq 0x2270
leaq 0xdba7(%rip), %rdi      # 0x2d8d6
jmp 0x1fd21