// File: /workspace/github_cpp_makefile_star2_O2/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, %ebx
movsd %xmm0, 0x30(%rsp)
movl %edx, %ebp
movq %rsi, %r15
movq %rdi, %r14
movq (%rdi), %rdi
movq 0x8(%r14), %rsi
leaq -0x74ce(%rip), %rdx     # 0x13497
callq 0x17bcf
pushq $0x18
popq %r12
movq %r12, %rdi
callq 0x2170
movslq %ebx, %rcx
movq %rcx, 0x28(%rsp)
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq %rax, 0x8(%rsp)
andq $0x0, 0x10(%rax)
xorl %ecx, %ecx
movl %ebp, 0x10(%rsp)
movl %ebp, %edx
subl %ecx, %edx
jle 0x1ab5b
movq 0x28(%rsp), %rax
leaq (%rcx,%rax), %rsi
movq %rsi, 0x38(%rsp)
cmpl %ebp, %esi
cmovlel %eax, %edx
leal (%rdx,%rcx), %esi
cmpl %ebp, %esi
movl %ebp, %eax
movl %esi, 0x14(%rsp)
cmovll %esi, %eax
cltq
xorl %r9d, %r9d
movq %rcx, 0x20(%rsp)
cmpq %rax, %rcx
jge 0x1a9ec
cvtsi2sd %r9d, %xmm0
movsd (%r15,%rcx,8), %xmm1
ucomisd %xmm0, %xmm1
cvttsd2si %xmm1, %esi
cmoval %esi, %r9d
incq %rcx
jmp 0x1a9cb
movq %r15, %rdi
movl %ebp, %esi
movq 0x20(%rsp), %rbp
movl %ebp, %ecx
movsd 0x30(%rsp), %xmm0
pushq $0x1
popq %r8
callq 0x19847
movsd %xmm0, 0x18(%rsp)
movq %r12, %rdi
callq 0x2170
movq %rax, %r13
andq $0x0, 0x10(%rax)
movsd 0x18(%rsp), %xmm0
ucomisd 0x9685(%rip), %xmm0     # 0x240b0
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
jbe 0x1ab36
xorl %ebx, %ebx
movq 0x8(%r14), %rax
subq (%r14), %rax
shrq $0x3, %rax
cltq
cmpq %rax, %rbx
jge 0x1ab36
movq %r14, %rdi
movq %rbx, %rsi
callq 0x7404
movq (%rax), %rax
cmpl %ebp, 0xc(%rax)
jl 0x1ab2e
movq %r14, %rdi
movq %rbx, %rsi
callq 0x7404
movq (%rax), %rax
movl 0x14(%rsp), %ecx
cmpl %ecx, 0xc(%rax)
jge 0x1ab2e
movq %r14, %rdi
movq %rbx, %rsi
callq 0x7404
movq (%rax), %rax
movslq 0xc(%rax), %r12
leaq (%r15,%r12,8), %rbp
movq %r14, %rdi
movq %rbx, %rsi
callq 0x7404
movq (%rax), %rax
movslq 0x20(%rax), %rax
cmpq %rax, %r12
jg 0x1aac4
movq %r13, %rdi
movq %rbp, %rsi
callq 0x7426
incq %r12
addq $0x8, %rbp
jmp 0x1aa99
movq (%r13), %rdi
movq 0x8(%r13), %rsi
callq 0x1c411
movq 0x8(%r13), %rsi
subq (%r13), %rsi
sarq $0x3, %rsi
shrq %rsi
movq %r13, %rdi
callq 0x7466
movsd (%rax), %xmm0
ucomisd 0x18(%rsp), %xmm0
jbe 0x1ab1b
movq %r14, %rdi
movq %rbx, %rsi
callq 0x7404
movq (%rax), %rdi
callq 0x134b2
movq %rax, 0x40(%rsp)
movq 0x8(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0xd00a
movq (%r13), %rax
cmpq %rax, 0x8(%r13)
movq 0x20(%rsp), %rbp
je 0x1ab2e
movq %rax, 0x8(%r13)
incq %rbx
jmp 0x1aa3b
movq %r13, %rdi
callq 0xd13a
movq %r13, %rdi
pushq $0x18
popq %r12
movq %r12, %rsi
callq 0x2180
movq 0x38(%rsp), %rcx
movl 0x10(%rsp), %ebp
jmp 0x1a996
cmpb $0x1, 0x1a666(%rip)     # 0x351c8
je 0x1ab78
movq 0x8(%rsp), %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x1a461(%rip), %rax     # 0x34fe0
movq (%rax), %rdi
movq 0x8(%r14), %rdx
subq (%r14), %rdx
shrq $0x3, %rdx
movq 0x8(%rsp), %rax
movq 0x8(%rax), %rcx
subq (%rax), %rcx
shrq $0x3, %rcx
leaq 0xd64e(%rip), %rsi      # 0x281f2
xorl %eax, %eax
callq 0x2240
jmp 0x1ab64