// File: /workspace/github_cpp_makefile_star2_O2/gersteinlab[P]MUSIC/src/ms_filter_utils.cpp
// Function: mean_filter_data(double*, int, int, int)
double* mean_filter_data(double* track_data,
						int l_track_data, 
						int l_averaging_win,
						int skip_value) // This is the value to be skipped from the window values.
{
	// Do copying from start to end.
    double* cur_filtered_track = new double[l_track_data + 2];

	int half_l_averaging = l_averaging_win / 2;
		
	// Initialize the current pdf.
	double cur_total_win_val = 0;
	bool val_inited = false;

	int prev_avg_start = -1;
	int prev_avg_end = -1;

	// Go over all the positions as the middle of the filtering window.
	for(int cur_win_mid = 1; cur_win_mid <= l_track_data; cur_win_mid++)
	{
		cur_filtered_track[cur_win_mid] = 0;

		int cur_avg_start = (cur_win_mid > half_l_averaging)?(cur_win_mid - half_l_averaging):(1);
		int cur_avg_end = (cur_win_mid + half_l_averaging <= l_track_data)?(cur_win_mid + half_l_averaging):(l_track_data);
		if(!val_inited)
		{
			for(int i = cur_avg_start; i <= cur_avg_end; i++)
			{
				cur_total_win_val += track_data[i];
			} // i loop.

			val_inited = true;
		}
		else
		{
			// Exclude the signal values that got out of the current window.
			for(int i = prev_avg_start; i < cur_avg_start; i++)
			{
				cur_total_win_val -= track_data[i];
			} // i loop.

			// Add the signal values that entered the current window.
			for(int i = prev_avg_end+1; i <= cur_avg_end; i++)
			{
				cur_total_win_val += track_data[i];
			} // i loop.
		}

		// Following does a sanity check for the computed values.
if(__DUMP_FILTER_MSGS__)
{
		double check_val = 0;
		for(int i = cur_avg_start; i <= cur_avg_end; i++)
		{
			check_val += track_data[i];
		} // i loop.

		if(fabs(check_val - cur_total_win_val) > 2)
		{
			fprintf(stderr, "Check failed: %d: %lf, %lf\n", cur_win_mid, check_val, cur_total_win_val);
			exit(0);
		}
}

		cur_filtered_track[cur_win_mid] = cur_total_win_val / (cur_avg_end - cur_avg_start + 1);

		prev_avg_start = cur_avg_start;
		prev_avg_end = cur_avg_end;
	} // main signal filtering loop.

	return(cur_filtered_track);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %edx, %ebp
movl %esi, %ebx
movq %rdi, %r14
leal 0x2(%rbx), %eax
shlq $0x3, %rax
cmpl $-0x2, %esi
pushq $-0x1
popq %rdi
cmovgeq %rax, %rdi
callq 0x2040
movq %rax, %rcx
pushq $0x2
popq %rsi
movl %ebp, %eax
cltd
idivl %esi
movb 0x259b8(%rip), %sil     # 0x351c5
cltq
xorl %r15d, %r15d
testl %ebx, %ebx
movl $0x0, %edi
cmovgl %ebx, %edi
incl %edi
xorpd %xmm1, %xmm1
pushq $-0x1
popq %r12
pushq $0x1
popq %rdx
pushq $0x1
popq %r8
movapd 0x171ab(%rip), %xmm2    # 0x269e0
movsd 0x1482b(%rip), %xmm3    # 0x24068
movl %r12d, %ebp
cmpq %rdi, %rdx
je 0xf902
movl %edx, %r9d
subl %eax, %r9d
cmpq %rax, %rdx
cmovlel %r8d, %r9d
leal (%rax,%rdx), %r10d
cmpl %ebx, %r10d
cmovgel %ebx, %r10d
movslq %r10d, %r11
testb $0x1, %r15b
je 0xf894
movslq %r12d, %r15
movslq %r9d, %r12
cmpq %r12, %r15
jge 0xf880
subsd (%r14,%r15,8), %xmm1
incq %r15
jmp 0xf870
movslq %ebp, %r15
cmpq %r11, %r15
jge 0xf8a7
addsd 0x8(%r14,%r15,8), %xmm1
incq %r15
jmp 0xf883
movslq %r9d, %r15
cmpq %r11, %r15
jg 0xf8a7
addsd (%r14,%r15,8), %xmm1
incq %r15
jmp 0xf897
testb $0x1, %sil
je 0xf8d6
movslq %r9d, %r15
xorpd %xmm0, %xmm0
cmpq %r11, %r15
jg 0xf8c4
addsd (%r14,%r15,8), %xmm0
incq %r15
jmp 0xf8b4
movapd %xmm0, %xmm4
subsd %xmm1, %xmm4
andpd %xmm2, %xmm4
ucomisd %xmm3, %xmm4
ja 0xf90e
movl %r10d, %r11d
subl %r9d, %r11d
incl %r11d
cvtsi2sd %r11d, %xmm0
movapd %xmm1, %xmm4
divsd %xmm0, %xmm4
movsd %xmm4, (%rcx,%rdx,8)
incq %rdx
movb $0x1, %r15b
movl %r9d, %r12d
movl %r10d, %ebp
jmp 0xf840
movq %rcx, %rax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq 0x256cb(%rip), %rax     # 0x34fe0
movq (%rax), %rdi
leaq 0x17d18(%rip), %rsi     # 0x27637
movb $0x2, %al
callq 0x2240
xorl %edi, %edi
callq 0x21d0