// File: /workspace/github_cpp_makefile_star2_O2/melop[P]admixem/config.cpp
// Function: RecombProbConfigurations::GetBreakPointsByArm(bool, int, int, std::vector<double, std::allocator<double>>&)
void RecombProbConfigurations::GetBreakPointsByArm(bool bSex, int nChr, int nArm,vector<double> &vRet) { // return a vector of break points for a given arm of a given chromosome for a given sex
	
		#ifdef _OPENMP
		int nCPU = omp_get_thread_num();
			#ifdef DEBUG
			printf("CPU %d: %s : %d\n", nCPU, "SexSelFormulae # ", nCPU);
			#endif
		#else
			int nCPU = 0;
		#endif
	//double nExpectedPoints = (true==bSex? (nArm==1? _nExpectedMaleRecPerMeiosisArm1[nChr] : _nExpectedMaleRecPerMeiosisArm2[nChr]) : (nArm==1? _nExpectedFemaleRecPerMeiosisArm1[nChr] : _nExpectedFemaleRecPerMeiosisArm2[nChr]));
	//int nBreakPointsToPut = (int)nExpectedPoints; // get integral part
	//nBreakPointsToPut += (UniformGen.Next() <= (nExpectedPoints - (double)nBreakPointsToPut)) ? 1:0;
	Poisson * pPoissonGen = (true==bSex? (nArm==1?  pvMaleRecArm1Gen[nCPU][nChr] : pvMaleRecArm2Gen[nCPU][nChr]) : (nArm==1? pvFemaleRecArm1Gen[nCPU][nChr] : pvFemaleRecArm2Gen[nCPU][nChr]));; 
	int nBreakPointsToPut = pPoissonGen->Next();
	
	double nCentromerePos = ((SimulationConfigurations*)this->_pParentConfig)->pMarkerConfig->GetCentromerePosition(nChr);
	double nChrLen = ((SimulationConfigurations*)this->_pParentConfig)->pMarkerConfig->GetChromosomeLength(nChr);

	double nStart = (nArm==1)? 0.0 : nCentromerePos;
	double nEnd   = (nArm==1)? nCentromerePos : nChrLen;

	//vector<double> * pvAccuProb;
	tk::spline * pvAccuProbSpline;
	size_t nCentromereIndex, nLastIndex, nStartIndex, nEndIndex;

	if (!this->_bUseUniform) {
		//pvAccuProb = true==bSex? pvMaleAccuProb : pvFemaleAccuProb;
		if (bSex) {
			pvAccuProbSpline = nArm==1? &vMaleAccuProbSplineArm1[nChr] : &vMaleAccuProbSplineArm2[nChr];
		}
		else {
			pvAccuProbSpline = nArm==1? &vFemaleAccuProbSplineArm1[nChr] : &vFemaleAccuProbSplineArm2[nChr];
		}
		//nCentromereIndex = std::distance( pvBreakpointSamplePositions[nChr].begin(), lower_bound(pvBreakpointSamplePositions[nChr].begin(),pvBreakpointSamplePositions[nChr].end(), nCentromerePos));
		//nLastIndex = std::distance(pvBreakpointSamplePositions[nChr].begin() , pvBreakpointSamplePositions[nChr].end());
		//nStartIndex = (nArm==1)? 0 : nCentromereIndex + 1;
		//nEndIndex = (nArm==1)? nCentromereIndex : nLastIndex;
	}
	
	//printf("Breakpointstoput for sex %d Chr %d Arm %d: %d\n", bSex, nChr, nArm, nBreakPointsToPut);
	//vector<double>::iterator it_start = lower_bound(pvAccuProb[nChr]begin(), pvAccuProb->end(), nStart);

	for (int i=0;i<nBreakPointsToPut;i++) {

		double nRand = vUniformGen[nCPU]->Next();
		if (!this->_bUseUniform) {
			/*
			std::vector<double>::iterator oLowerBound;
			oLowerBound = lower_bound( pvAccuProb[nChr].begin() + nStartIndex, pvAccuProb[nChr].begin() + nEndIndex, nRand);
			size_t nLowerBoundIndex = std::distance(pvAccuProb[nChr].begin(), oLowerBound);
			if (nLowerBoundIndex == 0 || nLowerBoundIndex==nEndIndex) {
				// the first element
				i--;
				continue; //break point cannot be inserted at the tips
			}
			//vector<double>::iterator oPreviousPoint = oLowerBound - 1;
			double nPos1 = pvBreakpointSamplePositions[nChr].at(nLowerBoundIndex - 1);
			double nPos2 = pvBreakpointSamplePositions[nChr].at(nLowerBoundIndex);
			//interpolate
			vRet.push_back( (nPos1 + nPos2) / 2 );
			*/
			//new code that uses spline interpolation
			vRet.push_back((*pvAccuProbSpline)(nRand));
		} else {
			double nArmLen = nEnd - nStart;
			double nBpPos = (nArm==1)? (nArmLen * nRand) : (nCentromerePos + nArmLen * nRand);
			vRet.push_back(nBpPos);
		}
		
	}

	sort(vRet.begin(), vRet.end());


}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r8, %r12
movl %esi, %r15d
movq %rdi, %r14
xorl %eax, %eax
movl %ecx, 0xc(%rsp)
cmpl $0x1, %ecx
setne %al
movslq %edx, %rbx
movl %r15d, %ecx
xorb $0x1, %cl
movzbl %cl, %ecx
shll $0x4, %ecx
leal (%rcx,%rax,8), %eax
movq 0x50(%rax,%rdi), %rax
movq (%rax), %rax
movq (%rax,%rbx,8), %rdi
movq (%rdi), %rax
callq *(%rax)
movq (%r14), %rax
movq (%rax), %rax
movq 0x48(%rax), %rcx
cmpb $0x0, 0x70(%r14)
je 0x11b56
movsd (%rcx,%rbx,8), %xmm1
cvttsd2si %xmm0, %ecx
movsd %xmm1, 0x18(%rsp)
movsd %xmm1, 0x20(%rsp)
cmpl $0x1, 0xc(%rsp)
je 0x119ec
movq 0x30(%rax), %rax
movsd (%rax,%rbx,8), %xmm0
subsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
xorl %ebx, %ebx
testl %ecx, %ecx
cmovgl %ecx, %ebx
leaq 0x340c6(%rip), %r15     # 0x45ac0
subl $0x1, %ebx
jb 0x11b39
movq (%r15), %rax
movq (%rax), %rdi
movq (%rdi), %rax
callq *(%rax)
cmpb $0x0, 0x70(%r14)
je 0x11a45
cmpl $0x1, 0xc(%rsp)
je 0x11a2a
mulsd 0x20(%rsp), %xmm0
addsd 0x18(%rsp), %xmm0
jmp 0x11a30
mulsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movq %r12, %rdi
leaq 0x10(%rsp), %rsi
callq 0x170a2
jmp 0x119fa
movq %r14, %r15
movq %r12, %r14
movsd %xmm0, 0x10(%rsp)
movq (%rbp), %r13
movq 0x8(%rbp), %r12
movq %r13, %rdi
movq %r12, %rsi
leaq 0x10(%rsp), %rdx
callq 0x183fd
movq (%rbp), %rcx
subq %rcx, %rax
shrq $0x3, %rax
cmpl $0x2, %eax
pushq $0x1
popq %rdx
cmovll %edx, %eax
decl %eax
movsd 0x10(%rsp), %xmm1
movapd %xmm1, %xmm0
subsd (%rcx,%rax,8), %xmm0
movsd (%rcx), %xmm2
ucomisd %xmm1, %xmm2
jbe 0x11aaf
movsd 0x78(%rbp), %xmm1
mulsd %xmm0, %xmm1
addsd 0x80(%rbp), %xmm1
movq 0x18(%rbp), %rcx
jmp 0x11b13
subq %r13, %r12
sarq $0x3, %r12
ucomisd -0x8(%rcx,%r12,8), %xmm1
jbe 0x11ae4
movq 0x48(%rbp), %rax
movq 0x60(%rbp), %rcx
movsd -0x8(%rax,%r12,8), %xmm1
mulsd %xmm0, %xmm1
addsd -0x8(%rcx,%r12,8), %xmm1
leaq -0x1(%r12), %rcx
shlq $0x3, %rcx
jmp 0x11b0f
leaq (,%rax,8), %rcx
movq 0x30(%rbp), %rdx
movq 0x48(%rbp), %rsi
movsd (%rdx,%rax,8), %xmm1
mulsd %xmm0, %xmm1
addsd (%rsi,%rax,8), %xmm1
movq 0x60(%rbp), %rdx
mulsd %xmm0, %xmm1
addsd (%rdx,%rax,8), %xmm1
addq 0x18(%rbp), %rcx
mulsd %xmm0, %xmm1
addsd (%rcx), %xmm1
movsd %xmm1, 0x10(%rsp)
movq %r14, %r12
movq %r14, %rdi
leaq 0x10(%rsp), %rsi
callq 0x1a60c
movq %r15, %r14
jmp 0x119f3
movq (%r12), %rdi
movq 0x8(%r12), %rsi
callq 0x1a70a
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testb %r15b, %r15b
je 0x11b75
cmpl $0x1, 0xc(%rsp)
jne 0x11b8f
imulq $0xa8, %rbx, %rbp
addq 0x90(%r14), %rbp
jmp 0x119bb
cmpl $0x1, 0xc(%rsp)
jne 0x11ba2
imulq $0xa8, %rbx, %rbp
addq 0xa8(%r14), %rbp
jmp 0x119bb
imulq $0xa8, %rbx, %rbp
addq 0xc0(%r14), %rbp
jmp 0x119bb
imulq $0xa8, %rbx, %rbp
addq 0xd8(%r14), %rbp
jmp 0x119bb
nop