// File: 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:
subq $0xb8, %rsp
movq %rdi, 0xb0(%rsp)
movq %rsi, 0xa8(%rsp)
movl %edx, 0xa4(%rsp)
movsd %xmm0, 0x98(%rsp)
movl %ecx, 0x94(%rsp)
movl $0x1, 0x90(%rsp)
movl 0x94(%rsp), %eax
movl %eax, 0x8c(%rsp)
movq 0xb0(%rsp), %rdi
callq 0xc7d0
movq %rax, 0x80(%rsp)
movq 0xb0(%rsp), %rdi
callq 0xc760
movq %rax, 0x78(%rsp)
movq 0x80(%rsp), %rdi
movq 0x78(%rsp), %rsi
leaq -0xd432(%rip), %rdx     # 0x2a3a0
callq 0x31d00
movl 0x90(%rsp), %eax
cmpl 0xa4(%rsp), %eax
jge 0x37cae
movl 0x90(%rsp), %eax
addl 0x94(%rsp), %eax
cmpl 0xa4(%rsp), %eax
jle 0x37819
movl 0xa4(%rsp), %eax
subl 0x90(%rsp), %eax
movl %eax, 0x8c(%rsp)
jmp 0x37827
movl 0x94(%rsp), %eax
movl %eax, 0x8c(%rsp)
movl $0x0, 0x74(%rsp)
movl 0x90(%rsp), %eax
movl %eax, 0x70(%rsp)
movl 0x70(%rsp), %ecx
movl 0x90(%rsp), %edx
addl 0x8c(%rsp), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, 0x5a(%rsp)
jge 0x37868
movl 0x70(%rsp), %eax
cmpl 0xa4(%rsp), %eax
setl %al
movb %al, 0x5a(%rsp)
movb 0x5a(%rsp), %al
testb $0x1, %al
jne 0x37872
jmp 0x378b5
cvtsi2sdl 0x74(%rsp), %xmm1
movq 0xa8(%rsp), %rax
movslq 0x70(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x378a6
movq 0xa8(%rsp), %rax
movslq 0x70(%rsp), %rcx
cvttsd2si (%rax,%rcx,8), %eax
movl %eax, 0x74(%rsp)
jmp 0x378a8
movl 0x70(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x70(%rsp)
jmp 0x3783a
movq 0xa8(%rsp), %rdi
movl 0xa4(%rsp), %esi
movl 0x8c(%rsp), %edx
movl 0x90(%rsp), %ecx
movsd 0x98(%rsp), %xmm0
movl 0x74(%rsp), %r9d
movl $0x1, %r8d
callq 0x36100
movsd %xmm0, 0x68(%rsp)
movq $0x0, 0x60(%rsp)
testb $0x1, 0x2d8df(%rip)     # 0x651e0
je 0x3791b
leaq 0x1ec4d(%rip), %rdi     # 0x56557
leaq 0x1bfbc(%rip), %rsi     # 0x538cd
callq 0x455f0
movq %rax, 0x60(%rsp)
movl $0x0, 0x5c(%rsp)
movsd 0x68(%rsp), %xmm0
xorl %eax, %eax
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
movb %al, 0x59(%rsp)
jbe 0x3795d
movl 0x5c(%rsp), %eax
movl %eax, 0x54(%rsp)
movq 0xb0(%rsp), %rdi
callq 0xc680
movq %rax, %rcx
movl 0x54(%rsp), %eax
cmpl %ecx, %eax
setl %al
movb %al, 0x59(%rsp)
movb 0x59(%rsp), %al
testb $0x1, %al
jne 0x3796a
jmp 0x37c82
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0xc(%rax), %eax
cmpl 0x90(%rsp), %eax
jl 0x37c70
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0xc(%rax), %eax
movl 0x90(%rsp), %ecx
addl 0x8c(%rsp), %ecx
cmpl %ecx, %eax
jge 0x37c70
movb $0x0, 0x5b(%rsp)
movq 0xa8(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq %rax, %rcx
movq 0x48(%rsp), %rax
movq (%rcx), %rcx
movslq 0xc(%rcx), %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd 0x68(%rsp), %xmm0
jb 0x37a8f
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0xc(%rax), %ecx
subl $0x64, %ecx
movl %ecx, 0xc(%rax)
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
cmpl $0x1, 0xc(%rax)
jge 0x37a45
movl $0x1, %eax
movl %eax, 0x44(%rsp)
jmp 0x37a61
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0xc(%rax), %eax
movl %eax, 0x44(%rsp)
movl 0x44(%rsp), %eax
movl %eax, 0x40(%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movl 0x40(%rsp), %ecx
movq (%rax), %rax
movl %ecx, 0xc(%rax)
movb $0x1, 0x5b(%rsp)
jmp 0x37b61
movq 0xa8(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq %rax, %rcx
movq 0x38(%rsp), %rax
movq (%rcx), %rcx
movslq 0x20(%rcx), %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd 0x68(%rsp), %xmm0
jb 0x37b5f
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0x20(%rax), %ecx
addl $0x64, %ecx
movl %ecx, 0x20(%rax)
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0x20(%rax), %eax
cmpl 0xa4(%rsp), %eax
jle 0x37b1a
movl 0xa4(%rsp), %eax
movl %eax, 0x34(%rsp)
jmp 0x37b36
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0x20(%rax), %eax
movl %eax, 0x34(%rsp)
movl 0x34(%rsp), %eax
movl %eax, 0x30(%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movl 0x30(%rsp), %ecx
movq (%rax), %rax
movl %ecx, 0x20(%rax)
movb $0x1, 0x5b(%rsp)
jmp 0x37b61
cmpq $0x0, 0x60(%rsp)
je 0x37c6e
testb $0x1, 0x5b(%rsp)
je 0x37c6e
movq 0x60(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movq (%rax), %rax
movq %rax, 0x10(%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0xc(%rax), %eax
movl %eax, 0x18(%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0x20(%rax), %eax
movl %eax, 0x1c(%rsp)
movq 0xa8(%rsp), %rax
movq %rax, (%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq %rax, %rcx
movq (%rsp), %rax
movq (%rcx), %rcx
movslq 0xc(%rcx), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x20(%rsp)
movq 0xa8(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rdx
movl 0x18(%rsp), %ecx
movl 0x1c(%rsp), %r8d
movsd 0x20(%rsp), %xmm0
movq %rax, %rsi
movq 0x28(%rsp), %rax
movq (%rsi), %rsi
movslq 0x20(%rsi), %rsi
movsd (%rax,%rsi,8), %xmm1
movsd 0x68(%rsp), %xmm2
leaq 0x1e904(%rip), %rsi     # 0x5656b
movb $0x3, %al
callq 0x2250
jmp 0x37c70
jmp 0x37c72
movl 0x5c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5c(%rsp)
jmp 0x37923
cmpq $0x0, 0x60(%rsp)
je 0x37c94
movq 0x60(%rsp), %rdi
callq 0x2180
movl 0x94(%rsp), %eax
addl 0x90(%rsp), %eax
movl %eax, 0x90(%rsp)
jmp 0x377d7
addq $0xb8, %rsp
retq
nopw %cs:(%rax,%rax)