// File: /workspace/github_cpp_makefile_star2_O3/gersteinlab[P]MUSIC/src/ms_peak_calling_utils.cpp
// Function: set_per_strand_info_per_peaks(std::vector<t_annot_region*, std::allocator<t_annot_region*>>*, char*, char*, int)
vector<t_annot_region*>* set_per_strand_info_per_peaks(vector<t_annot_region*>* peak_regions,
		char* chrom,
		char* chip_reads_dir,
		int l_fragment)
{
	vector<char*>* chr_ids = NULL;

	if(chrom == NULL)
	{
		char chr_ids_fp[1000];
		sprintf(chr_ids_fp, "%s/chr_ids.txt", chip_reads_dir);
		chr_ids = buffer_file(chr_ids_fp);
		if(chr_ids == NULL)
		{
			fprintf(stderr, "Could not load the chromosome id's for the chip data.\n");
			exit(0);
		}
	}
	else
	{
		chr_ids = new vector<char*>();
		chr_ids->push_back(t_string::copy_me_str(chrom));
	}

	// Process each chromosome.
	vector<t_annot_region*>* filtered_peaks = new vector<t_annot_region*>();
	for(int i_chr = 0; i_chr < (int)chr_ids->size(); i_chr++)
	{
if(__DUMP_PEAK_CALLING_UTILS_MSGS__)
		fprintf(stderr, "%s..", chr_ids->at(i_chr));

		// Skip chromosome M for now.
		if(strcmp(chr_ids->at(i_chr), "M") == 0)
		{
			continue;
		}

		// Generate the current signal profile.
		int l_buffer = 300*1000*1000;
		int l_profile = 0;
		double* forward_signal = new double[l_buffer + 2];	
		double* reverse_signal = new double[l_buffer + 2];	
		char cur_chr_chip_reads_fp[1000];
		sprintf(cur_chr_chip_reads_fp, "%s/%s_mapped_reads.txt", chip_reads_dir, chr_ids->at(i_chr));
		buffer_per_nucleotide_profile_no_buffer(cur_chr_chip_reads_fp, l_fragment, 
			NULL, forward_signal, reverse_signal,
			l_buffer, l_profile);

if(__DBG__)
{
		double* new_f_signal_profile = replace_profiles_for_debug(forward_signal, l_profile, g_dbg_base_posn, g_dbg_l_new_profile);
		double* new_r_signal_profile = replace_profiles_for_debug(reverse_signal, l_profile, g_dbg_base_posn, g_dbg_l_new_profile);
		delete [] forward_signal;
		delete [] reverse_signal;
		forward_signal = new_f_signal_profile;
		reverse_signal = new_r_signal_profile;
		l_profile = g_dbg_l_new_profile;
}

if(__DUMP_PEAK_CALLING_UTILS_MSGS__)
{
		char fore_strand_signal_fp[1000];
		sprintf(fore_strand_signal_fp, "%s_fore_strand.bin", chr_ids->at(i_chr));
		dump_per_nucleotide_binary_profile(forward_signal, l_profile, fore_strand_signal_fp);
		char rev_strand_signal_fp[1000];
		sprintf(rev_strand_signal_fp, "%s_rev_strand.bin", chr_ids->at(i_chr));
		dump_per_nucleotide_binary_profile(reverse_signal, l_profile, rev_strand_signal_fp);
}
			
		vector<t_annot_region*>* cur_chr_regs = get_regions_per_chromosome(peak_regions, chr_ids->at(i_chr));

if(__DUMP_PEAK_CALLING_UTILS_MSGS__)
		fprintf(stderr, "Filtering %d regions on chromosome %s\n", (int)cur_chr_regs->size(), chr_ids->at(i_chr));
			
		//int n_passing_peaks = 0;
		for(int i_reg = 0; i_reg < (int)cur_chr_regs->size(); i_reg++)
		{
			t_ER_info* cur_peak_info = (t_ER_info*)(cur_chr_regs->at(i_reg)->data);

			double total_forward_signal = 0.0;
			double total_reverse_signal = 0.0;
			double total_fore_moment = 0;
			double total_rev_moment = 0;
			cur_peak_info->fore_max_val = 0;
			cur_peak_info->fore_climax_posn = 0;
			cur_peak_info->rev_max_val = 0;
			cur_peak_info->rev_climax_posn = 0;

			// Process forward strand info.
			for(int i = cur_chr_regs->at(i_reg)->start; i <= cur_chr_regs->at(i_reg)->end; i++)
			{
				if(i < l_profile)
				{
					total_forward_signal += forward_signal[i];
					total_fore_moment += (i - cur_chr_regs->at(i_reg)->start + 1) * forward_signal[i];

					if(cur_peak_info->fore_max_val < forward_signal[i])
					{
						cur_peak_info->fore_max_val = forward_signal[i];
						cur_peak_info->fore_climax_posn = i;
					}
				}
			} // i loop.

			// Process reverse strand info.
			for(int i = cur_chr_regs->at(i_reg)->end; i >= cur_chr_regs->at(i_reg)->start; i--)
			{
				if(i < l_profile)
				{
					total_reverse_signal += reverse_signal[i];
					total_rev_moment += (i - cur_chr_regs->at(i_reg)->start + 1) * reverse_signal[i];

					if(cur_peak_info->rev_max_val < reverse_signal[i])
					{
						cur_peak_info->rev_max_val = reverse_signal[i];
						cur_peak_info->rev_climax_posn = i;
					}
				}
			} // i loop.

			cur_peak_info->total_fore_mass = total_forward_signal;
			cur_peak_info->total_rev_mass = total_reverse_signal;

			cur_peak_info->fore_strand_mass_of_center = (int)(total_fore_moment / total_forward_signal) + cur_chr_regs->at(i_reg)->start;
			cur_peak_info->rev_strand_mass_of_center = (int)(total_rev_moment / total_reverse_signal) + cur_chr_regs->at(i_reg)->start;
		} // i_reg loop.

		//fprintf(stderr, "%s: %d peaks passed. (%d)\n", chr_ids->at(i_chr), n_passing_peaks, (int)cur_chr_regs->size());

		// For each peak, compute the fraction of read signal that is in mapable regions.
		delete [] forward_signal;
		delete [] reverse_signal;
		delete cur_chr_regs;
	} // chromosome loop.

	//dump_BED("filtered_peaks.bed", filtered_peaks);
	//dump_BED("removed_peaks.bed", removed_peaks);
	//delete removed_peaks;

	t_string::clean_string_list(chr_ids);

	return(filtered_peaks);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc18, %rsp            # imm = 0xC18
movl %ecx, 0x34(%rsp)
movq %rdi, 0x40(%rsp)
testq %rsi, %rsi
movq %rdx, 0x48(%rsp)
je 0xf4a8
movq %rsi, %rbx
movl $0x18, %edi
callq 0x2180
movq %rax, %r14
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq $0x0, 0x10(%rax)
movq %rbx, %rdi
callq 0x26db4
leaq 0x50(%rsp), %rsi
movq %rax, (%rsi)
movq %r14, %rdi
callq 0xb27c
jmp 0xf4d2
leaq 0x1b52f(%rip), %rsi     # 0x2a9de
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2080
movq %rbx, %rdi
callq 0x25af8
testq %rax, %rax
je 0xf9af
movq %rax, %r14
movl $0x18, %edi
callq 0x2180
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq %rax, 0x38(%rsp)
movq $0x0, 0x10(%rax)
movq (%r14), %rax
movq 0x8(%r14), %rcx
movq %rcx, %rdx
subq %rax, %rdx
sarq $0x3, %rdx
testl %edx, %edx
jle 0xf96a
xorl %esi, %esi
movq %r14, 0x20(%rsp)
cmpb $0x1, 0x29cb2(%rip)     # 0x391ca
movq %rsi, 0x18(%rsp)
je 0xf8b2
movq %rcx, %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %rsi, %rdx
jbe 0xf995
movq (%rax,%rsi,8), %rdx
cmpb $0x4d, (%rdx)
jne 0xf549
cmpb $0x0, 0x1(%rdx)
je 0xf8ad
movl $0x0, 0x14(%rsp)
movl $0x8f0d1810, %edi       # imm = 0x8F0D1810
callq 0x2040
movq %rax, %r15
movl $0x8f0d1810, %edi       # imm = 0x8F0D1810
callq 0x2040
movq 0x18(%rsp), %rsi
movq %rax, %rbx
movq (%r14), %rax
movq 0x8(%r14), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %rsi, %rdx
jbe 0xf995
movq (%rax,%rsi,8), %rcx
leaq 0x50(%rsp), %r14
movq %r14, %rdi
leaq 0x1b49e(%rip), %rsi     # 0x2aa38
movq 0x48(%rsp), %rdx
xorl %eax, %eax
callq 0x2080
leaq 0x14(%rsp), %rax
movq %rax, (%rsp)
movq %r14, %rdi
movl 0x34(%rsp), %esi
xorl %edx, %edx
movq %r15, %rcx
movq %rbx, %r8
movl $0x11e1a300, %r9d       # imm = 0x11E1A300
callq 0x11f57
cmpb $0x1, 0x29bfb(%rip)     # 0x391cb
je 0xf8e8
cmpb $0x1, 0x29bed(%rip)     # 0x391ca
movq 0x18(%rsp), %rsi
jne 0xf67d
movq 0x20(%rsp), %r14
movq (%r14), %rax
movq 0x8(%r14), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %rsi, %rdx
jbe 0xf995
movq (%rax,%rsi,8), %rdx
leaq 0x830(%rsp), %r12
movq %r12, %rdi
leaq 0x1dc73(%rip), %rsi     # 0x2d28d
xorl %eax, %eax
callq 0x2080
movl 0x14(%rsp), %esi
movq %r15, %rdi
movq %r12, %rdx
callq 0x1d226
movq 0x18(%rsp), %rsi
movq (%r14), %rax
movq 0x8(%r14), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %rsi, %rdx
jbe 0xf995
movq (%rax,%rsi,8), %rdx
leaq 0x440(%rsp), %r14
movq %r14, %rdi
leaq 0x1dc3e(%rip), %rsi     # 0x2d2a0
xorl %eax, %eax
callq 0x2080
movl 0x14(%rsp), %esi
movq %rbx, %rdi
movq %r14, %rdx
callq 0x1d226
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %rsi, %rdx
jbe 0xf995
movq (%rax,%rsi,8), %rsi
movq 0x40(%rsp), %rdi
callq 0x19bcb
movq %rax, %rdi
cmpb $0x1, 0x29b19(%rip)     # 0x391ca
movq %rax, 0x28(%rsp)
je 0xf93b
movq (%rdi), %rax
movq 0x8(%rdi), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
testl %edx, %edx
xorps %xmm7, %xmm7
jle 0xf83c
movslq 0x14(%rsp), %rcx
movl %edx, %esi
andl $0x7fffffff, %esi       # imm = 0x7FFFFFFF
xorl %edi, %edi
cmpq %rdx, %rdi
je 0xf989
movq (%rax,%rdi,8), %r10
movq 0x48(%r10), %r8
movups %xmm7, 0x10(%r8)
movq $0x0, 0x20(%r8)
movslq 0xc(%r10), %r9
movslq 0x20(%r10), %r10
xorpd %xmm1, %xmm1
xorpd %xmm0, %xmm0
cmpl %r10d, %r9d
jg 0xf806
movl %r9d, %r11d
leaq (%r15,%r9,8), %rbp
movl %r10d, %r12d
notl %r12d
addq %r11, %r12
xorpd %xmm3, %xmm3
xorl %r14d, %r14d
xorpd %xmm0, %xmm0
xorpd %xmm2, %xmm2
leaq (%r9,%r14), %r13
cmpq %rcx, %r13
jge 0xf778
movsd (%rbp,%r14,8), %xmm1
addsd %xmm1, %xmm2
leal 0x1(%r14), %r13d
xorps %xmm4, %xmm4
cvtsi2sd %r13d, %xmm4
mulsd %xmm1, %xmm4
addsd %xmm4, %xmm0
ucomisd %xmm3, %xmm1
jbe 0xf778
leaq (%r11,%r14), %r13
movsd %xmm1, 0x18(%r8)
movl %r13d, 0x10(%r8)
jmp 0xf77c
movapd %xmm3, %xmm1
incq %r14
movl %r12d, %r13d
movapd %xmm1, %xmm3
addl %r14d, %r13d
jne 0xf73a
xorpd %xmm1, %xmm1
unpcklpd %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
xorpd %xmm0, %xmm0
unpcklpd %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0]
cmpl %r10d, %r9d
jg 0xf806
movl $0x1, %r14d
subl %r11d, %r14d
xorpd %xmm4, %xmm4
xorpd %xmm2, %xmm2
xorpd %xmm3, %xmm3
cmpq %rcx, %r10
jge 0xf7ea
movsd (%rbx,%r10,8), %xmm5
addsd %xmm5, %xmm3
leal (%r14,%r10), %r11d
xorps %xmm6, %xmm6
cvtsi2sd %r11d, %xmm6
mulsd %xmm5, %xmm6
addsd %xmm6, %xmm2
ucomisd %xmm4, %xmm5
jbe 0xf7ea
movsd %xmm5, 0x20(%r8)
movl %r10d, 0x14(%r8)
jmp 0xf7ee
movapd %xmm4, %xmm5
leaq -0x1(%r10), %r11
movapd %xmm5, %xmm4
cmpq %r9, %r10
movq %r11, %r10
jg 0xf7b5
movsd %xmm3, %xmm0            # xmm0 = xmm3[0],xmm0[1]
movsd %xmm2, %xmm1            # xmm1 = xmm2[0],xmm1[1]
divpd %xmm0, %xmm1
cvttpd2dq %xmm1, %xmm1
movd %r9d, %xmm2
pshufd $0x50, %xmm2, %xmm2     # xmm2 = xmm2[0,0,1,1]
paddd %xmm1, %xmm2
shufpd $0x1, %xmm0, %xmm0      # xmm0 = xmm0[1,0]
cvtdq2pd %xmm2, %xmm1
movupd %xmm0, 0x28(%r8)
movupd %xmm1, (%r8)
incq %rdi
cmpq %rsi, %rdi
jne 0xf6e4
movq %r15, %rdi
callq 0x2220
movq %rbx, %rdi
callq 0x2220
movq 0x28(%rsp), %rax
movq (%rax), %rdi
testq %rdi, %rdi
je 0xf86a
movq 0x10(%rax), %rsi
subq %rdi, %rsi
callq 0x2190
movq 0x28(%rsp), %rax
movl $0x18, %esi
movq %rax, %rdi
callq 0x2190
movq 0x20(%rsp), %r14
movq (%r14), %rax
movq 0x8(%r14), %rdi
movq %rdi, %rcx
movq 0x18(%rsp), %rsi
incq %rsi
subq %rax, %rdi
movq %rdi, %rdx
sarq $0x3, %rdx
shrq $0x3, %rdi
movslq %edi, %rdi
cmpq %rdi, %rsi
jl 0xf511
jmp 0xf96a
movq %rcx, %rdi
jmp 0xf88b
cmpq %rsi, %rdx
jbe 0xf995
movq 0x2971e(%rip), %rcx     # 0x38fe0
movq (%rcx), %rdi
movq (%rax,%rsi,8), %rdx
leaq 0x1d2cb(%rip), %rsi     # 0x2cb9b
xorl %eax, %eax
callq 0x2250
movq 0x18(%rsp), %rsi
movq (%r14), %rax
movq 0x8(%r14), %rcx
jmp 0xf523
movl 0x298d6(%rip), %edx     # 0x391c4
movl 0x298cc(%rip), %ecx     # 0x391c0
movq %r15, %rdi
callq 0x2ec3
movq %rax, %r14
movl 0x298bf(%rip), %edx     # 0x391c4
movl 0x298b5(%rip), %ecx     # 0x391c0
movq %rbx, %rdi
callq 0x2ec3
movq %rax, %rbp
movq %r15, %rdi
callq 0x2220
movq %rbx, %rdi
callq 0x2220
movl 0x29894(%rip), %eax     # 0x391c0
movl %eax, 0x14(%rsp)
movq %rbp, %rbx
movq %r14, %r15
jmp 0xf5d6
movq 0x20(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
subq %rsi, %rdx
sarq $0x3, %rdx
movq 0x18(%rsp), %rax
cmpq %rax, %rdx
jbe 0xf9a3
movq %rax, %rdx
callq 0x376d
movq 0x28(%rsp), %rdi
jmp 0xf6bc
movq %r14, %rdi
callq 0x2859a
movq 0x38(%rsp), %rax
addq $0xc18, %rsp            # imm = 0xC18
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1cf40(%rip), %rdi     # 0x2c8d0
movq %rdx, %rsi
jmp 0xf99c
leaq 0x1cf34(%rip), %rdi     # 0x2c8d0
xorl %eax, %eax
callq 0x2270
leaq 0x1cf26(%rip), %rdi     # 0x2c8d0
movq %rax, %rsi
jmp 0xf99c
callq 0x379c