// File: /workspace/github_cpp_makefile_star2_O1/gersteinlab[P]MUSIC/src/ms_peak_calling_utils.cpp
// Function: filter_strand_uneven_peaks(std::vector<t_annot_region*, std::allocator<t_annot_region*>>*, char*, char*, int, double)
vector<t_annot_region*>* filter_strand_uneven_peaks(vector<t_annot_region*>* peak_regions,
		char* chrom,
		char* chip_reads_dir,
		int l_fragment,
		double min_forward_reverse_strand_signal_fraction)
{
	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*>();
	//vector<t_annot_region*>* removed_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(__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);
}

if(__DBG__)
{
		// Replace fore/rev signals.
		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;
}

		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++)
		{
			double total_forward_signal = 0.0;
			double total_reverse_signal = 0.0;
			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_reverse_signal += reverse_signal[i];
				}
			} // i loop.

			// Both strand signals much be larger than 0.
			if(total_forward_signal > 0 &&
				total_reverse_signal > 0 &&
				total_reverse_signal / total_forward_signal > min_forward_reverse_strand_signal_fraction &&
				total_forward_signal / total_reverse_signal > min_forward_reverse_strand_signal_fraction)
			{
				t_annot_region* new_region = duplicate_region(cur_chr_regs->at(i_reg));
				filtered_peaks->push_back(new_region);
				n_passing_peaks++;
			}
			else
			{
				//removed_peaks->push_back(cur_chr_regs->at(i_reg));
			}
		} // 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
movapd %xmm0, 0x30(%rsp)
movl %ecx, 0x2c(%rsp)
movq %rdx, %r15
movq %rdi, 0x48(%rsp)
testq %rsi, %rsi
je 0x1067f
movq %rsi, %rbx
movl $0x18, %edi
callq 0x2180
movq %rax, %r12
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq $0x0, 0x10(%rax)
movq %rbx, %rdi
callq 0x273e0
leaq 0x440(%rsp), %rsi
movq %rax, (%rsi)
movq %r12, %rdi
callq 0xb476
jmp 0x106af
leaq 0x1b35e(%rip), %rsi     # 0x2b9e4
leaq 0x440(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rdx
xorl %eax, %eax
callq 0x2080
movq %rbx, %rdi
callq 0x2613e
testq %rax, %rax
je 0x10b50
movq %rax, %r12
movl $0x18, %edi
callq 0x2180
movq %rax, %rbp
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq $0x0, 0x10(%rax)
movq (%r12), %rax
movq 0x8(%r12), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
testl %edx, %edx
jle 0x10afe
movapd 0x30(%rsp), %xmm0
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
movapd %xmm0, 0x30(%rsp)
leaq 0x1b202(%rip), %r14     # 0x2b8fd
xorl %r13d, %r13d
movq %r12, 0x20(%rsp)
movq %r15, 0x40(%rsp)
cmpb $0x1, 0x29abb(%rip)     # 0x3a1ca
je 0x10761
movq (%r12), %rax
movq 0x8(%r12), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %r13, %rdx
jbe 0x10b2a
movq (%rax,%r13,8), %rdi
movq %r14, %rsi
callq 0x2240
testl %eax, %eax
jne 0x10788
incq %r13
movq (%r12), %rax
movq 0x8(%r12), %rcx
subq %rax, %rcx
movq %rcx, %rdx
sarq $0x3, %rdx
shrq $0x3, %rcx
movslq %ecx, %rcx
cmpq %rcx, %r13
jl 0x10708
jmp 0x10afe
cmpq %r13, %rdx
jbe 0x10b2a
movq 0x2986f(%rip), %rcx     # 0x39fe0
movq (%rcx), %rdi
movq (%rax,%r13,8), %rdx
leaq 0x1d41c(%rip), %rsi     # 0x2db9b
xorl %eax, %eax
callq 0x2250
jmp 0x10711
movl $0x0, 0x14(%rsp)
movl $0x8f0d1810, %edi       # imm = 0x8F0D1810
callq 0x2040
movq %rax, %rbx
movl $0x8f0d1810, %edi       # imm = 0x8F0D1810
callq 0x2040
movq %rax, %r14
movq (%r12), %rax
movq 0x8(%r12), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %r13, %rdx
jbe 0x10b2a
movq %r13, 0x18(%rsp)
movq (%rax,%r13,8), %rcx
leaq 0x440(%rsp), %r13
movq %r13, %rdi
leaq 0x1b260(%rip), %rsi     # 0x2ba3e
movq %r15, %rdx
xorl %eax, %eax
callq 0x2080
leaq 0x14(%rsp), %rax
movq %rax, (%rsp)
movq %r13, %rdi
movl 0x2c(%rsp), %esi
xorl %edx, %edx
movq %rbx, %rcx
movq %r14, %r8
movl $0x11e1a300, %r9d       # imm = 0x11E1A300
callq 0x1225e
cmpb $0x1, 0x299b8(%rip)     # 0x3a1ca
jne 0x108a4
movq (%r12), %rax
movq 0x8(%r12), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movq 0x18(%rsp), %r13
cmpq %r13, %rdx
jbe 0x10b2a
movq (%rax,%r13,8), %rdx
leaq 0x50(%rsp), %r15
movq %r15, %rdi
leaq 0x1da44(%rip), %rsi     # 0x2e28d
xorl %eax, %eax
callq 0x2080
movl 0x14(%rsp), %esi
movq %rbx, %rdi
movq %r15, %rdx
callq 0x1d6be
movq (%r12), %rax
movq 0x8(%r12), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %r13, %rdx
jbe 0x10b2a
movq (%rax,%r13,8), %rdx
leaq 0x830(%rsp), %r15
movq %r15, %rdi
leaq 0x1da12(%rip), %rsi     # 0x2e2a0
xorl %eax, %eax
callq 0x2080
movl 0x14(%rsp), %esi
movq %r14, %rdi
movq %r15, %rdx
callq 0x1d6be
cmpb $0x1, 0x29920(%rip)     # 0x3a1cb
jne 0x10900
movl 0x29911(%rip), %edx     # 0x3a1c4
movl 0x29907(%rip), %ecx     # 0x3a1c0
movq %rbx, %rdi
callq 0x2ec3
movq %rax, %r15
movl 0x298fa(%rip), %edx     # 0x3a1c4
movl 0x298f0(%rip), %ecx     # 0x3a1c0
movq %r14, %rdi
callq 0x2ec3
movq %rax, %r12
movq %rbx, %rdi
callq 0x2220
movq %r14, %rdi
callq 0x2220
movl 0x298cf(%rip), %eax     # 0x3a1c0
movl %eax, 0x14(%rsp)
movq %r15, %rbx
movq %r12, %r14
movq 0x20(%rsp), %r12
movq (%r12), %rax
movq 0x8(%r12), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movq 0x18(%rsp), %rsi
cmpq %rsi, %rdx
jbe 0x10b3b
movq (%rax,%rsi,8), %rsi
movq 0x48(%rsp), %rdi
callq 0x1a008
movq %rax, %r15
cmpb $0x1, 0x29894(%rip)     # 0x3a1ca
jne 0x10961
movq (%r12), %rsi
movq 0x8(%r12), %rdx
subq %rsi, %rdx
sarq $0x3, %rdx
movq 0x18(%rsp), %rax
cmpq %rax, %rdx
jbe 0x10b44
movq %r15, %rdi
movq %rax, %rdx
callq 0x3905
movq (%r15), %rax
movq 0x8(%r15), %rdx
movq %rdx, %r8
subq %rax, %r8
sarq $0x3, %r8
xorl %r12d, %r12d
testl %r8d, %r8d
jle 0x10a72
xorl %r13d, %r13d
xorl %r12d, %r12d
xorpd %xmm3, %xmm3
cmpq %r13, %r8
jbe 0x10b1b
movq (%rax,%r13,8), %rcx
movslq 0xc(%rcx), %rax
movl 0x20(%rcx), %ecx
xorpd %xmm0, %xmm0
cmpl %ecx, %eax
jg 0x109c8
movslq 0x14(%rsp), %rsi
subl %eax, %ecx
incl %ecx
cmpq %rsi, %rax
jge 0x109c1
movsd (%rbx,%rax,8), %xmm1
movhpd (%r14,%rax,8), %xmm1    # xmm1 = xmm1[0],mem[0]
addpd %xmm1, %xmm0
incq %rax
decl %ecx
jne 0x109ad
movapd %xmm0, %xmm1
shufpd $0x1, %xmm0, %xmm1      # xmm1 = xmm1[1],xmm0[0]
movapd %xmm0, %xmm2
divpd %xmm1, %xmm2
movapd 0x30(%rsp), %xmm1
cmpltpd %xmm2, %xmm1
movmskpd %xmm1, %eax
cmpl $0x3, %eax
sete %al
ucomisd %xmm3, %xmm0
jbe 0x10a4b
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
ucomisd %xmm3, %xmm0
jbe 0x10a4b
testb %al, %al
je 0x10a4b
movq (%r15), %rax
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %r13, %rdx
jbe 0x10b2a
movq (%rax,%r13,8), %rdi
callq 0x172ac
movq %rax, 0x50(%rsp)
movq 0x8(%rbp), %rsi
cmpq 0x10(%rbp), %rsi
je 0x10a37
movq %rax, (%rsi)
addq $0x8, 0x8(%rbp)
jmp 0x10a44
movq %rbp, %rdi
leaq 0x50(%rsp), %rdx
callq 0xb976
xorpd %xmm3, %xmm3
incl %r12d
incq %r13
movq (%r15), %rax
movq 0x8(%r15), %rdx
movq %rdx, %rcx
subq %rax, %rcx
movq %rcx, %r8
sarq $0x3, %r8
shrq $0x3, %rcx
movslq %ecx, %rcx
cmpq %rcx, %r13
jl 0x10988
movq 0x20(%rsp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movq 0x18(%rsp), %rsi
cmpq %rsi, %rdx
jbe 0x10b3b
movq 0x29546(%rip), %rcx     # 0x39fe0
movq (%rcx), %rdi
movq (%rax,%rsi,8), %rdx
leaq 0x1d661(%rip), %rsi     # 0x2e109
movl %r12d, %ecx
xorl %eax, %eax
callq 0x2250
movq %rbx, %rdi
callq 0x2220
movq %r14, %rdi
callq 0x2220
movq (%r15), %rdi
testq %rdi, %rdi
je 0x10ad6
movq 0x10(%r15), %rsi
subq %rdi, %rsi
callq 0x2190
movl $0x18, %esi
movq %r15, %rdi
callq 0x2190
movq 0x40(%rsp), %r15
movq 0x20(%rsp), %r12
movq 0x18(%rsp), %r13
leaq 0x1ae04(%rip), %r14     # 0x2b8fd
jmp 0x1073a
movq %r12, %rdi
callq 0x28cb4
movq %rbp, %rax
addq $0xc18, %rsp            # imm = 0xC18
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1cdb4(%rip), %rdi     # 0x2d8d6
movq %r13, %rsi
movq %r8, %rdx
jmp 0x10b34
leaq 0x1cda5(%rip), %rdi     # 0x2d8d6
movq %r13, %rsi
xorl %eax, %eax
callq 0x2270
leaq 0x1cd94(%rip), %rdi     # 0x2d8d6
jmp 0x10b34
leaq 0x1cd8b(%rip), %rdi     # 0x2d8d6
movq %rax, %rsi
jmp 0x10b34
callq 0x3934
nop