// File: /workspace/github_cpp_makefile_star2_O2/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, %ebx
movsd %xmm0, 0x30(%rsp)
movl %edx, %r12d
movq %rsi, %r14
movq %rdi, %r15
movq (%rdi), %rdi
movq 0x8(%r15), %rsi
leaq -0x6f93(%rip), %rdx     # 0x13497
callq 0x17bcf
movslq %ebx, %rax
movq %rax, 0x28(%rsp)
pushq $0x1
popq %r13
movl %r12d, 0x20(%rsp)
movl %r12d, %edx
subl %r13d, %edx
jle 0x1a6f4
movq 0x28(%rsp), %rax
leaq (%rax,%r13), %rdi
cmpl %r12d, %edi
cmovlel %eax, %edx
leal (%rdx,%r13), %ecx
cmpl %r12d, %ecx
movl %r12d, %eax
movl %ecx, 0x24(%rsp)
cmovll %ecx, %eax
cltq
xorl %r9d, %r9d
movq %r13, %rcx
cmpq %rax, %rcx
jge 0x1a495
cvtsi2sd %r9d, %xmm0
movsd (%r14,%rcx,8), %xmm1
ucomisd %xmm0, %xmm1
cvttsd2si %xmm1, %esi
cmoval %esi, %r9d
incq %rcx
jmp 0x1a474
movq %rdi, 0x38(%rsp)
movq %r14, %rdi
movl %r12d, %esi
movl %r13d, %ecx
movsd 0x30(%rsp), %xmm0
pushq $0x1
popq %r8
callq 0x19847
cmpb $0x0, 0x1ad0f(%rip)     # 0x351c8
movsd %xmm0, 0x10(%rsp)
je 0x1a4e1
leaq 0xdce3(%rip), %rdi      # 0x281ab
leaq 0xb3a3(%rip), %rsi      # 0x25872
callq 0x2027c
movsd 0x10(%rsp), %xmm0
movq %rax, 0x8(%rsp)
jmp 0x1a4ea
movq $0x0, 0x8(%rsp)
ucomisd 0x9bbe(%rip), %xmm0     # 0x240b0
jbe 0x1a6d1
xorl %ebp, %ebp
movq 0x8(%r15), %rax
subq (%r15), %rax
shrq $0x3, %rax
cltq
cmpq %rax, %rbp
jge 0x1a6d1
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
cmpl %r13d, 0xc(%rax)
jl 0x1a6c9
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
movl 0x24(%rsp), %ecx
cmpl %ecx, 0xc(%rax)
jge 0x1a6c9
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
movslq 0xc(%rax), %rax
movsd (%r14,%rax,8), %xmm0
movsd %xmm0, 0x18(%rsp)
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movsd 0x10(%rsp), %xmm1
movsd 0x18(%rsp), %xmm0
ucomisd %xmm1, %xmm0
movq (%rax), %rax
jae 0x1a5e2
movslq 0x20(%rax), %rax
movsd (%r14,%rax,8), %xmm0
ucomisd %xmm1, %xmm0
jb 0x1a6c9
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
addl $0x64, 0x20(%rax)
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
movl %r12d, %ebx
cmpl %r12d, 0x20(%rax)
jg 0x1a5cf
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
movl 0x20(%rax), %ebx
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
movl %ebx, 0x20(%rax)
jmp 0x1a61f
addl $-0x64, 0xc(%rax)
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
cmpl $0x0, 0xc(%rax)
pushq $0x1
popq %rbx
jle 0x1a60e
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
movl 0xc(%rax), %ebx
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
movl %ebx, 0xc(%rax)
cmpq $0x0, 0x8(%rsp)
je 0x1a6c9
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
movq (%rax), %rax
movq %rax, 0x18(%rsp)
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
movl 0xc(%rax), %r12d
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
movl 0x20(%rax), %ebx
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
movslq 0xc(%rax), %rax
movsd (%r14,%rax,8), %xmm0
movsd %xmm0, 0x40(%rsp)
movq %r15, %rdi
movq %rbp, %rsi
callq 0x7404
movq (%rax), %rax
movslq 0x20(%rax), %rax
movsd (%r14,%rax,8), %xmm1
movq 0x8(%rsp), %rdi
leaq 0xdb19(%rip), %rsi      # 0x281bf
movq 0x18(%rsp), %rdx
movl %r12d, %ecx
movl 0x20(%rsp), %r12d
movl %ebx, %r8d
movsd 0x40(%rsp), %xmm0
movsd 0x10(%rsp), %xmm2
movb $0x3, %al
callq 0x2240
incq %rbp
jmp 0x1a4fa
movq 0x38(%rsp), %rbx
movq %rbx, %r13
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x1a440
callq 0x2160
movq %rbx, %r13
jmp 0x1a440
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq