// File: /workspace/github_cpp_makefile_star2_O3/gersteinlab[P]MUSIC/src/ms_signal_enrichment_utils.cpp
// Function: tune_regions_per_window_average_at_boundaries(std::vector<t_annot_region*, std::allocator<t_annot_region*>>*, double*, int, double, int)
void tune_regions_per_window_average_at_boundaries(vector<t_annot_region*>* regions, double* signal_profile, int l_profile,
	double fdr, int l_win)
{
	// Go over all the windows.
	int cur_win_start = 1;
	int cur_l_win = l_win;

	// Sort the regions.
	sort(regions->begin(), regions->end(), sort_regions);

	// 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);

		FILE* f_tuned_feat_ends = NULL;
			
		if(__DUMP_SIGNAL_ENRICHMENT_MSGS__)
		{
			f_tuned_feat_ends = open_f("tuned_feat_ends.bed", "a");
		}

		// 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))
			{
				bool reg_tuned = false;

				// Following is actually a very weak and unstable check, we must evaluate whether there is high signal around the start/end of this region.
				if(signal_profile[regions->at(i_reg)->start] >= cur_win_thresh)
				{
					regions->at(i_reg)->start -= 100;
					regions->at(i_reg)->start = (regions->at(i_reg)->start < 1)?(1):(regions->at(i_reg)->start);					

					reg_tuned = true;
				}
				else if(signal_profile[regions->at(i_reg)->end] >= cur_win_thresh)
				{
					regions->at(i_reg)->end += 100;
					regions->at(i_reg)->end = (regions->at(i_reg)->end > l_profile)?(l_profile):(regions->at(i_reg)->end);

					reg_tuned = true;
				}

				// If the region is tuned, dump the region, if we are dumping.
				if(f_tuned_feat_ends != NULL &&
					reg_tuned)
				{
					fprintf(f_tuned_feat_ends, "%s\t%d\t%d\t%.3f %.3f %.3f\t.\t+\n", 
							regions->at(i_reg)->chrom, regions->at(i_reg)->start, regions->at(i_reg)->end,
							signal_profile[regions->at(i_reg)->start], signal_profile[regions->at(i_reg)->end], cur_win_thresh);
				}
			}
		} // i_reg loop.

		if(f_tuned_feat_ends != NULL)
		{
			fclose(f_tuned_feat_ends);
		}

		// Update window.
		cur_win_start += l_win;
	} // window start check.
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl %ecx, 0x2c(%rsp)
movsd %xmm0, 0x40(%rsp)
movl %edx, 0x14(%rsp)
movq %rsi, %r14
movq %rdi, %r15
movq (%rdi), %r12
movq 0x8(%rdi), %r13
cmpq %r13, %r12
je 0x1eda9
movq %r13, %rbx
subq %r12, %rbx
movq %rbx, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x7d04(%rip), %rcx     # 0x16f04
movq %r12, %rdi
movq %r13, %rsi
callq 0x1c455
leaq 0x8(%r12), %rax
cmpq $0x81, %rbx
movq %r13, 0x18(%rsp)
jl 0x1ed29
movl $0x8, %r13d
movq %rax, 0x38(%rsp)
movq %rax, %rbp
movq %r12, 0x30(%rsp)
movq %r12, 0x20(%rsp)
movq 0x30(%rsp), %r12
leaq (%r12,%r13), %rax
movq %rax, 0x8(%rsp)
movq (%r12,%r13), %rdi
movq (%r12), %rsi
callq 0x16f04
movq (%r12,%r13), %rbx
testb %al, %al
je 0x1ec77
movq 0x38(%rsp), %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0x22b0
jmp 0x1ecb1
movq 0x20(%rsp), %rax
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x16f04
movq 0x8(%rsp), %r12
testb %al, %al
je 0x1ecb1
movq %rbp, %rcx
leaq -0x8(%rcx), %r12
movq -0x10(%rcx), %rsi
movq -0x8(%rcx), %rax
movq %rax, (%rcx)
movq %rbx, %rdi
callq 0x16f04
movq %r12, %rcx
testb %al, %al
jne 0x1ec93
movq %rbx, (%r12)
addq $0x8, %r13
addq $0x8, %rbp
cmpq $0x80, %r13
movq 0x8(%rsp), %r12
jne 0x1ec3d
movq 0x30(%rsp), %r12
subq $-0x80, %r12
cmpq 0x18(%rsp), %r12
je 0x1eda9
movq -0x8(%r12), %rsi
movq (%r12), %rbx
movq %rbx, %rdi
callq 0x16f04
movq %r12, %r13
testb %al, %al
je 0x1ed1c
movq %r13, %rcx
leaq -0x8(%rcx), %r12
movq -0x10(%rcx), %rsi
movq -0x8(%rcx), %rax
movq %rax, (%rcx)
movq %rbx, %rdi
callq 0x16f04
movq %r12, %rcx
testb %al, %al
jne 0x1ecfe
movq %rbx, (%r12)
movq %r13, %r12
addq $0x8, %r12
jmp 0x1ecd8
cmpq %r13, %rax
je 0x1eda9
movq %r12, %rbp
movq %rbp, %rbx
movq %rax, %rbp
movq (%rax), %rdi
movq (%r12), %rsi
callq 0x16f04
movq (%rbp), %r13
testb %al, %al
je 0x1ed68
movq %rbp, %rdx
subq %r12, %rdx
subq %rdx, %rbx
addq $0x10, %rbx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x22b0
movq %r12, %rbx
jmp 0x1ed9b
movq (%rbx), %rsi
movq %r13, %rdi
callq 0x16f04
movq %rbp, %rbx
testb %al, %al
je 0x1ed9b
movq %rbp, %rcx
leaq -0x8(%rcx), %rbx
movq -0x10(%rcx), %rsi
movq -0x8(%rcx), %rax
movq %rax, (%rcx)
movq %r13, %rdi
callq 0x16f04
movq %rbx, %rcx
testb %al, %al
jne 0x1ed7d
movq %r13, (%rbx)
leaq 0x8(%rbp), %rax
cmpq 0x18(%rsp), %rax
jne 0x1ed31
movl 0x14(%rsp), %esi
cmpl $0x2, %esi
jl 0x1ef7c
movslq 0x2c(%rsp), %rax
movq %rax, 0x18(%rsp)
movl $0x1, %r12d
movq 0x18(%rsp), %rax
leaq (%r12,%rax), %rcx
movl %esi, %edx
subl %r12d, %edx
movq %rcx, 0x20(%rsp)
cmpl %esi, %ecx
cmovlel %eax, %edx
leal (%rdx,%r12), %ebx
cmpl %esi, %ebx
movl %esi, %eax
cmovll %ebx, %eax
movl $0x0, %r9d
cmpl %r12d, %eax
jle 0x1ee20
cltq
xorl %edi, %edi
movq %r12, %rcx
xorps %xmm0, %xmm0
cvtsi2sd %edi, %xmm0
movsd (%r14,%rcx,8), %xmm1
ucomisd %xmm0, %xmm1
cvttsd2si %xmm1, %r9d
cmovbel %edi, %r9d
incq %rcx
movl %r9d, %edi
cmpq %rax, %rcx
jl 0x1edfb
movq %r14, %rdi
movl %r12d, %ecx
movsd 0x40(%rsp), %xmm0
movl $0x1, %r8d
callq 0x1de93
movapd %xmm0, %xmm2
cmpb $0x0, 0x1a38e(%rip)     # 0x391d0
je 0x1ee68
leaq 0xf360(%rip), %rdi      # 0x2e1ab
leaq 0xca20(%rip), %rsi      # 0x2b872
movsd %xmm2, 0x8(%rsp)
callq 0x25d5a
movsd 0x8(%rsp), %xmm2
movq %rax, %r13
jmp 0x1ee6b
xorl %r13d, %r13d
ucomisd 0xb23d(%rip), %xmm2     # 0x2a0b0
jbe 0x1ef5b
movq (%r15), %rax
movq 0x8(%r15), %rdx
subq %rax, %rdx
movq %rdx, %rcx
shlq $0x1d, %rcx
movabsq $0x100000000, %rsi      # imm = 0x100000000
cmpq %rsi, %rcx
jl 0x1ef5b
xorl %ebp, %ebp
movsd %xmm2, 0x8(%rsp)
sarq $0x3, %rdx
cmpq %rbp, %rdx
jbe 0x1ef8b
movq (%rax,%rbp,8), %rcx
movl 0xc(%rcx), %eax
cmpl %r12d, %eax
jl 0x1ef3b
cmpl %ebx, %eax
jge 0x1ef3b
movslq %eax, %rdx
movsd (%r14,%rdx,8), %xmm0
ucomisd %xmm2, %xmm0
jae 0x1eef2
movslq 0x20(%rcx), %rdx
movsd (%r14,%rdx,8), %xmm0
ucomisd %xmm2, %xmm0
jb 0x1ef3b
addl $0x64, %edx
movl 0x14(%rsp), %esi
cmpl %esi, %edx
cmovgel %esi, %edx
movl %edx, 0x20(%rcx)
jmp 0x1ef03
cmpl $0x66, %eax
movl $0x65, %edx
cmovll %edx, %eax
addl $-0x64, %eax
movl %eax, 0xc(%rcx)
testq %r13, %r13
je 0x1ef3b
movq (%rcx), %rdx
movslq 0x20(%rcx), %r8
movslq %eax, %rcx
movsd (%r14,%rcx,8), %xmm0
movsd (%r14,%r8,8), %xmm1
movq %r13, %rdi
leaq 0xf297(%rip), %rsi      # 0x2e1bf
movsd 0x8(%rsp), %xmm2
movb $0x3, %al
callq 0x2250
movsd 0x8(%rsp), %xmm2
incq %rbp
movq (%r15), %rax
movq 0x8(%r15), %rdx
subq %rax, %rdx
movq %rdx, %rcx
shrq $0x3, %rcx
movslq %ecx, %rcx
cmpq %rcx, %rbp
jl 0x1eea5
testq %r13, %r13
je 0x1ef68
movq %r13, %rdi
callq 0x2170
movq 0x20(%rsp), %rax
movq %rax, %r12
movl 0x14(%rsp), %esi
cmpl %esi, %eax
jl 0x1edc6
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xd93e(%rip), %rdi      # 0x2c8d0
movq %rbp, %rsi
xorl %eax, %eax
callq 0x2270