// File: 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:
subq $0x1118, %rsp           # imm = 0x1118
movq %rdi, 0x1110(%rsp)
movq %rsi, 0x1108(%rsp)
movq %rdx, 0x1100(%rsp)
movl %ecx, 0x10fc(%rsp)
movq $0x0, 0x10f0(%rsp)
cmpq $0x0, 0x1108(%rsp)
jne 0x18ebc
leaq 0xd00(%rsp), %rdi
movq 0x1100(%rsp), %rdx
leaq 0x39b66(%rip), %rsi     # 0x529da
movb $0x0, %al
callq 0x2090
leaq 0xd00(%rsp), %rdi
callq 0x452c0
movq %rax, 0x10f0(%rsp)
cmpq $0x0, 0x10f0(%rsp)
jne 0x18eba
movq 0x4c13e(%rip), %rax     # 0x64fe0
movq (%rax), %rdi
leaq 0x3c076(%rip), %rsi     # 0x54f22
movb $0x0, %al
callq 0x2250
xorl %edi, %edi
callq 0x21f0
jmp 0x18f34
movl $0x18, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0xa0(%rsp)
xorl %esi, %esi
movl $0x18, %edx
callq 0x2110
movq 0xa0(%rsp), %rdi
callq 0xc630
movq 0xa0(%rsp), %rax
movq %rax, 0x10f0(%rsp)
movq 0x10f0(%rsp), %rax
movq %rax, 0xa8(%rsp)
movq 0x1108(%rsp), %rdi
callq 0x47b60
movq 0xa8(%rsp), %rdi
movq %rax, 0xcf8(%rsp)
leaq 0xcf8(%rsp), %rsi
callq 0xc640
movl $0x18, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0x98(%rsp)
xorl %esi, %esi
movl $0x18, %edx
callq 0x2110
movq 0x98(%rsp), %rdi
callq 0xc670
movq 0x98(%rsp), %rax
movq %rax, 0xcf0(%rsp)
movl $0x0, 0xcec(%rsp)
movl 0xcec(%rsp), %eax
movl %eax, 0x94(%rsp)
movq 0x10f0(%rsp), %rdi
callq 0xc220
movq %rax, %rcx
movl 0x94(%rsp), %eax
cmpl %ecx, %eax
jge 0x19824
testb $0x1, 0x4c229(%rip)     # 0x651da
je 0x18ff3
movq 0x4c026(%rip), %rax     # 0x64fe0
movq (%rax), %rax
movq %rax, 0x88(%rsp)
movq 0x10f0(%rsp), %rdi
movslq 0xcec(%rsp), %rsi
callq 0xc240
movq 0x88(%rsp), %rdi
movq (%rax), %rdx
leaq 0x3bf75(%rip), %rsi     # 0x54f61
movb $0x0, %al
callq 0x2250
movq 0x10f0(%rsp), %rdi
movslq 0xcec(%rsp), %rsi
callq 0xc240
movq (%rax), %rdi
leaq 0x39893(%rip), %rsi     # 0x528a5
callq 0x2240
cmpl $0x0, %eax
jne 0x19021
jmp 0x1980e
movl $0x11e1a300, 0xce8(%rsp) # imm = 0x11E1A300
movl $0x0, 0xce4(%rsp)
movl 0xce8(%rsp), %eax
addl $0x2, %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2040
movq %rax, 0xcd8(%rsp)
movl 0xce8(%rsp), %eax
addl $0x2, %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2040
movq %rax, 0xcd0(%rsp)
leaq 0x8e0(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0x1100(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0x10f0(%rsp), %rdi
movslq 0xcec(%rsp), %rsi
callq 0xc240
movq 0x78(%rsp), %rdi
movq 0x80(%rsp), %rdx
movq (%rax), %rcx
leaq 0x3994a(%rip), %rsi     # 0x52a34
movb $0x0, %al
callq 0x2090
leaq 0x8e0(%rsp), %rdi
movl 0x10fc(%rsp), %esi
movq 0xcd8(%rsp), %rcx
movq 0xcd0(%rsp), %r8
movl 0xce8(%rsp), %r9d
xorl %eax, %eax
movl %eax, %edx
leaq 0xce4(%rsp), %rax
movq %rax, (%rsp)
callq 0x1edf0
testb $0x1, 0x4c0a7(%rip)     # 0x651db
je 0x191f1
movq 0xcd8(%rsp), %rdi
movl 0xce4(%rsp), %esi
movl 0x4c085(%rip), %edx     # 0x651d4
movl 0x4c07b(%rip), %ecx     # 0x651d0
callq 0x12390
movq %rax, 0x8d8(%rsp)
movq 0xcd0(%rsp), %rdi
movl 0xce4(%rsp), %esi
movl 0x4c05d(%rip), %edx     # 0x651d4
movl 0x4c053(%rip), %ecx     # 0x651d0
callq 0x12390
movq %rax, 0x8d0(%rsp)
movq 0xcd8(%rsp), %rax
movq %rax, 0x70(%rsp)
cmpq $0x0, %rax
je 0x191a7
movq 0x70(%rsp), %rdi
callq 0x2220
movq 0xcd0(%rsp), %rax
movq %rax, 0x68(%rsp)
cmpq $0x0, %rax
je 0x191c4
movq 0x68(%rsp), %rdi
callq 0x2220
movq 0x8d8(%rsp), %rax
movq %rax, 0xcd8(%rsp)
movq 0x8d0(%rsp), %rax
movq %rax, 0xcd0(%rsp)
movl 0x4bfe6(%rip), %eax     # 0x651d0
movl %eax, 0xce4(%rsp)
testb $0x1, 0x4bfe2(%rip)     # 0x651da
je 0x192a6
leaq 0x4e0(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x10f0(%rsp), %rdi
movslq 0xcec(%rsp), %rsi
callq 0xc240
movq 0x58(%rsp), %rdi
movq (%rax), %rdx
leaq 0x3c424(%rip), %rsi     # 0x55653
movb $0x0, %al
callq 0x2090
movq 0xcd8(%rsp), %rdi
movl 0xce4(%rsp), %esi
leaq 0x4e0(%rsp), %rdx
callq 0x35140
leaq 0xf0(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x10f0(%rsp), %rdi
movslq 0xcec(%rsp), %rsi
callq 0xc240
movq 0x60(%rsp), %rdi
movq (%rax), %rdx
leaq 0x3c3e3(%rip), %rsi     # 0x55666
movb $0x0, %al
callq 0x2090
movq 0xcd0(%rsp), %rdi
movl 0xce4(%rsp), %esi
leaq 0xf0(%rsp), %rdx
callq 0x35140
movq 0x1110(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x10f0(%rsp), %rdi
movslq 0xcec(%rsp), %rsi
callq 0xc240
movq 0x50(%rsp), %rdi
movq (%rax), %rsi
callq 0x2e1e0
movq %rax, 0xe8(%rsp)
testb $0x1, 0x4bef6(%rip)     # 0x651da
je 0x19335
movq 0x4bcf3(%rip), %rax     # 0x64fe0
movq (%rax), %rax
movq %rax, 0x40(%rsp)
movq 0xe8(%rsp), %rdi
callq 0xc680
movl %eax, 0x4c(%rsp)
movq 0x10f0(%rsp), %rdi
movslq 0xcec(%rsp), %rsi
callq 0xc240
movq 0x40(%rsp), %rdi
movl 0x4c(%rsp), %edx
movq (%rax), %rcx
leaq 0x3c34a(%rip), %rsi     # 0x55678
movb $0x0, %al
callq 0x2250
movl $0x0, 0xe4(%rsp)
movl 0xe4(%rsp), %eax
movl %eax, 0x3c(%rsp)
movq 0xe8(%rsp), %rdi
callq 0xc680
movq %rax, %rcx
movl 0x3c(%rsp), %eax
cmpl %ecx, %eax
jge 0x197a6
movq 0xe8(%rsp), %rdi
movslq 0xe4(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movq 0x48(%rax), %rax
movq %rax, 0xd8(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0xd0(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0xc8(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0xc0(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0xb8(%rsp)
movq 0xd8(%rsp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, 0x18(%rax)
movq 0xd8(%rsp), %rax
movl $0x0, 0x10(%rax)
movq 0xd8(%rsp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, 0x20(%rax)
movq 0xd8(%rsp), %rax
movl $0x0, 0x14(%rax)
movq 0xe8(%rsp), %rdi
movslq 0xe4(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0xc(%rax), %eax
movl %eax, 0xb4(%rsp)
movl 0xb4(%rsp), %eax
movl %eax, 0x38(%rsp)
movq 0xe8(%rsp), %rdi
movslq 0xe4(%rsp), %rsi
callq 0xc800
movq %rax, %rcx
movl 0x38(%rsp), %eax
movq (%rcx), %rcx
cmpl 0x20(%rcx), %eax
jg 0x19562
movl 0xb4(%rsp), %eax
cmpl 0xce4(%rsp), %eax
jge 0x1954a
movq 0xcd8(%rsp), %rax
movslq 0xb4(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
addsd 0xd0(%rsp), %xmm0
movsd %xmm0, 0xd0(%rsp)
movl 0xb4(%rsp), %eax
movl %eax, 0x34(%rsp)
movq 0xe8(%rsp), %rdi
movslq 0xe4(%rsp), %rsi
callq 0xc800
movq %rax, %rcx
movl 0x34(%rsp), %eax
movq (%rcx), %rcx
subl 0xc(%rcx), %eax
addl $0x1, %eax
cvtsi2sd %eax, %xmm0
movq 0xcd8(%rsp), %rax
movslq 0xb4(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm2
movsd 0xc0(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0xc0(%rsp)
movq 0xd8(%rsp), %rax
movsd 0x18(%rax), %xmm1
movq 0xcd8(%rsp), %rax
movslq 0xb4(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x19548
movq 0xcd8(%rsp), %rax
movslq 0xb4(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0xd8(%rsp), %rax
movsd %xmm0, 0x18(%rax)
movl 0xb4(%rsp), %ecx
movq 0xd8(%rsp), %rax
movl %ecx, 0x10(%rax)
jmp 0x1954a
jmp 0x1954c
movl 0xb4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0x1941b
movq 0xe8(%rsp), %rdi
movslq 0xe4(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0x20(%rax), %eax
movl %eax, 0xb0(%rsp)
movl 0xb0(%rsp), %eax
movl %eax, 0x30(%rsp)
movq 0xe8(%rsp), %rdi
movslq 0xe4(%rsp), %rsi
callq 0xc800
movq %rax, %rcx
movl 0x30(%rsp), %eax
movq (%rcx), %rcx
cmpl 0xc(%rcx), %eax
jl 0x196cb
movl 0xb0(%rsp), %eax
cmpl 0xce4(%rsp), %eax
jge 0x196b3
movq 0xcd0(%rsp), %rax
movslq 0xb0(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
addsd 0xc8(%rsp), %xmm0
movsd %xmm0, 0xc8(%rsp)
movl 0xb0(%rsp), %eax
movl %eax, 0x2c(%rsp)
movq 0xe8(%rsp), %rdi
movslq 0xe4(%rsp), %rsi
callq 0xc800
movq %rax, %rcx
movl 0x2c(%rsp), %eax
movq (%rcx), %rcx
subl 0xc(%rcx), %eax
addl $0x1, %eax
cvtsi2sd %eax, %xmm0
movq 0xcd0(%rsp), %rax
movslq 0xb0(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm2
movsd 0xb8(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0xb8(%rsp)
movq 0xd8(%rsp), %rax
movsd 0x20(%rax), %xmm1
movq 0xcd0(%rsp), %rax
movslq 0xb0(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x196b1
movq 0xcd0(%rsp), %rax
movslq 0xb0(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0xd8(%rsp), %rax
movsd %xmm0, 0x20(%rax)
movl 0xb0(%rsp), %ecx
movq 0xd8(%rsp), %rax
movl %ecx, 0x14(%rax)
jmp 0x196b3
jmp 0x196b5
movl 0xb0(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0xb0(%rsp)
jmp 0x19584
movsd 0xd0(%rsp), %xmm0
movq 0xd8(%rsp), %rax
movsd %xmm0, 0x28(%rax)
movsd 0xc8(%rsp), %xmm0
movq 0xd8(%rsp), %rax
movsd %xmm0, 0x30(%rax)
movsd 0xc0(%rsp), %xmm0
divsd 0xd0(%rsp), %xmm0
cvttsd2si %xmm0, %eax
movl %eax, 0x24(%rsp)
movq 0xe8(%rsp), %rdi
movslq 0xe4(%rsp), %rsi
callq 0xc800
movq %rax, %rcx
movl 0x24(%rsp), %eax
movq (%rcx), %rcx
addl 0xc(%rcx), %eax
cvtsi2sd %eax, %xmm0
movq 0xd8(%rsp), %rax
movsd %xmm0, 0x8(%rax)
movsd 0xb8(%rsp), %xmm0
divsd 0xc8(%rsp), %xmm0
cvttsd2si %xmm0, %eax
movl %eax, 0x28(%rsp)
movq 0xe8(%rsp), %rdi
movslq 0xe4(%rsp), %rsi
callq 0xc800
movq %rax, %rcx
movl 0x28(%rsp), %eax
movq (%rcx), %rcx
addl 0xc(%rcx), %eax
cvtsi2sd %eax, %xmm0
movq 0xd8(%rsp), %rax
movsd %xmm0, (%rax)
movl 0xe4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe4(%rsp)
jmp 0x19340
movq 0xcd8(%rsp), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, %rax
je 0x197c3
movq 0x18(%rsp), %rdi
callq 0x2220
movq 0xcd0(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x197e0
movq 0x10(%rsp), %rdi
callq 0x2220
movq 0xe8(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x1980c
movq 0x8(%rsp), %rdi
callq 0xc970
movq 0x8(%rsp), %rdi
movl $0x18, %esi
callq 0x21a0
jmp 0x1980e
movl 0xcec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xcec(%rsp)
jmp 0x18f7d
movq 0x10f0(%rsp), %rdi
callq 0x49db0
movq 0xcf0(%rsp), %rax
addq $0x1118, %rsp           # imm = 0x1118
retq
nopw %cs:(%rax,%rax)