// File: /workspace/github_c_makefile_star2_O0/dapogon[P]cellcoal/src/cellcoal.c
// Function: ChooseTrinucleotideSite
int ChooseTrinucleotideSite (long int *seed, int *newState, int genome)
	{
	int	n1, n2, n3, r1, r2, r3, rest, index, trindex, trials;
	int	chosenSignature, chosenTriMutation, chosenPosition;
	int signID;
	TriNucStr *triNucleotide;
	
	if (genome == MATERNAL)
		triNucleotide = triNucleotideMaternal;
	else
		triNucleotide = triNucleotidePaternal;

	/* 1: Choose a mutation signature */
	signID = ChooseUniformState(signatureWeight, seed);
	chosenSignature = signatureID[signID];
		
	/* 2: Select a mutation out of the 96 possible ones for the choosen signature */
	//chosenTriMutation = ChooseTrinucMutation(geneticSignature[chosenSignature], seed);
	chosenTriMutation = ChooseUniformState(signatureProbs[chosenSignature-1], seed);

	/* 3: Define in which of the 64 trinucleotide classes this mutation will take place */
	r1 = chosenTriMutation/24;
	rest = chosenTriMutation%24;
	if (rest/4 < 3)
		r2 = C;
	else
		r2 = T;
	r3 = rest%4;

	if (RandomUniform(seed) > 0.5) //plus strand
		{
		n1 = r1;
		n2 = r2;
		n3 = r3;
		*newState = targetTriChange[rest/4];
		//fprintf (stderr, "\n\nplus strand");
		}
	else // minus strand
		{
		n1 = complementBase[r3];
		n2 = complementBase[r2];
		n3 = complementBase[r1];
		*newState = complementBase[targetTriChange[rest/4]];
		//fprintf (stderr, "\n\ncomplement reverse");
		}
		
	trindex = trinuc(n1,n2,n3);

	#ifdef PRINT_TRIMUTATIONS
	fprintf (stderr, "\n\nchosen triMutation (id %d) = %c%c%c",chosenTriMutation, WhichNuc(r1), WhichNuc(r2), WhichNuc(r3));
	fprintf (stderr, "\n%c%c%c [%d] => ", WhichNuc(n1), WhichNuc(n2), WhichNuc(n3), triNucleotide[trindex].numAvailablePositions);
	fprintf (stderr, "%c%c%c", WhichNuc(n1), WhichNuc(*newState), WhichNuc(n3));
	fprintf (stderr, " (%c>%c)", WhichNuc(n2), WhichNuc(*newState));
	#endif

	trials = 0;
	while (triNucleotide[trindex].numAvailablePositions == 0)
		{
		/* 1: Choose a mutation signature */
		signID = ChooseUniformState(signatureWeight, seed);
		chosenSignature = signatureID[signID];
		//fprintf (stderr,"\nchosenSignature = %d", chosenSignature);
		/* 2: Select a mutation out of the 96 possible ones for the choosen signature */
		chosenTriMutation = ChooseUniformState(signatureProbs[chosenSignature-1], seed);

		/* 3: Define the trinucleotide class where this mutation would take place */
		r1 = chosenTriMutation/24;
		rest = chosenTriMutation%24;
		if (rest/4 < 3)
			r2 = C;
		else
			r2 = T;
		r3 = rest%4;

		if (RandomUniform(seed) > 0.5) //plus strand
			{
			n1 = r1;
			n2 = r2;
			n3 = r3;
			*newState = targetTriChange[rest/4];
			//fprintf (stderr, "\nplus strand");
			}
		else // minus strand
			{
			n1 = complementBase[r3];
			n2 = complementBase[r2];
			n3 = complementBase[r1];
			*newState = complementBase[targetTriChange[rest/4]];
			//fprintf (stderr, "\ncomplement reverse");
			}
			
		trindex = trinuc(n1,n2,n3);
		
		#ifdef PRINT_TRIMUTATIONS
		fprintf (stderr, "\nnew chosen triMutation (id %d) = %c%c%c", chosenTriMutation, WhichNuc(r1), WhichNuc(r2), WhichNuc(r3));
		fprintf (stderr, "\n%c%c%c [%d] => ", WhichNuc(n1), WhichNuc(n2), WhichNuc(n3), triNucleotide[trindex].numAvailablePositions);
		fprintf (stderr, "%c%c%c", WhichNuc(n1), WhichNuc(*newState), WhichNuc(n3));
		fprintf (stderr, " (%c>%c)", WhichNuc(n2), WhichNuc(*newState));
		#endif

		if (trials++ > 100*numSites)
			{
			fprintf (stderr, "\n\nERROR: after %d trials cannot find an non-mutated trinuc site, increase the number of sites simulated\n\n",100*numSites);
			exit(-1);
			}
		}

	#ifdef PRINT_TRIMUTATIONS
		fprintf (stderr, "\nfinally chosen trimutation index = %d", chosenTriMutation);
	#endif
	
	/* 3: Select the genomic position where this mutation will take place */
	/* note we assume for convenience that the context is constant along the phylogeny */
	if (triNucleotide[trindex].numAvailablePositions == 1)
		index = 0;
	else if (triNucleotide[trindex].numAvailablePositions > 1)
		index = RandomUniformTo(triNucleotide[trindex].numAvailablePositions, seed);
	else
		{
		fprintf (stderr, "\n\nWe have a problem, no available trinucleotides\n");
		exit(-1);
		}

	chosenPosition = triNucleotide[trindex].position[index] + 1; 
	#ifdef PRINT_TRIMUTATIONS
		fprintf (stderr, "\nposition selected = %d", chosenPosition+1);
	#endif
	
	#ifdef PRINT_TRIMUTCOUNTER
	if (allSites[chosenPosition].numMutations == 0)
		triMutationsCounter[chosenTriMutation]++;
	#endif
	
	/* 4: remove the chosen position from the available list */
	RemoveTriNucObservation(&triNucleotide[trindex], index);

	return chosenPosition;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
jne 0x1b3f6
movq 0x34478(%rip), %rax     # 0x4f868
movq %rax, -0x58(%rbp)
jmp 0x1b401
movq 0x34473(%rip), %rax     # 0x4f870
movq %rax, -0x58(%rbp)
movq 0x344f8(%rip), %rdi     # 0x4f900
movq -0x8(%rbp), %rsi
callq 0x1a6f0
movl %eax, -0x4c(%rbp)
movq 0x344ed(%rip), %rax     # 0x4f908
movslq -0x4c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x40(%rbp)
leaq 0x34f8c(%rip), %rax     # 0x503b8
movq (%rax), %rax
movl -0x40(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rdi
movq -0x8(%rbp), %rsi
callq 0x1a6f0
movl %eax, -0x44(%rbp)
movl -0x44(%rbp), %eax
movl $0x18, %ecx
cltd
idivl %ecx
movl %eax, -0x24(%rbp)
movl -0x44(%rbp), %eax
movl $0x18, %ecx
cltd
idivl %ecx
movl %edx, -0x30(%rbp)
movl -0x30(%rbp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
cmpl $0x3, %eax
jge 0x1b47d
movl $0x1, -0x28(%rbp)
jmp 0x1b484
movl $0x3, -0x28(%rbp)
movl -0x30(%rbp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
movl %edx, -0x2c(%rbp)
movq -0x8(%rbp), %rdi
callq 0xa500
movsd 0x23b6d(%rip), %xmm1    # 0x3f010
ucomisd %xmm1, %xmm0
jbe 0x1b4db
movl -0x24(%rbp), %eax
movl %eax, -0x18(%rbp)
movl -0x28(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x30(%rbp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
movslq %eax, %rcx
leaq 0x32cc0(%rip), %rax     # 0x4e190
movl (%rax,%rcx,4), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
jmp 0x1b537
movslq -0x2c(%rbp), %rcx
leaq 0x32cca(%rip), %rax     # 0x4e1b0
movl (%rax,%rcx,4), %eax
movl %eax, -0x18(%rbp)
movslq -0x28(%rbp), %rcx
leaq 0x32cb9(%rip), %rax     # 0x4e1b0
movl (%rax,%rcx,4), %eax
movl %eax, -0x1c(%rbp)
movslq -0x24(%rbp), %rcx
leaq 0x32ca8(%rip), %rax     # 0x4e1b0
movl (%rax,%rcx,4), %eax
movl %eax, -0x20(%rbp)
movl -0x30(%rbp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
movslq %eax, %rcx
leaq 0x32c6d(%rip), %rax     # 0x4e190
movslq (%rax,%rcx,4), %rcx
leaq 0x32c82(%rip), %rax     # 0x4e1b0
movl (%rax,%rcx,4), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movl -0x18(%rbp), %eax
shll $0x4, %eax
movl -0x1c(%rbp), %ecx
shll $0x2, %ecx
addl %ecx, %eax
addl -0x20(%rbp), %eax
movl %eax, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movq -0x58(%rbp), %rax
movslq -0x38(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
cmpl $0x0, 0x4(%rax)
jne 0x1b6f9
movq 0x3438e(%rip), %rdi     # 0x4f900
movq -0x8(%rbp), %rsi
callq 0x1a6f0
movl %eax, -0x4c(%rbp)
movq 0x34383(%rip), %rax     # 0x4f908
movslq -0x4c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x40(%rbp)
leaq 0x34e22(%rip), %rax     # 0x503b8
movq (%rax), %rax
movl -0x40(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rdi
movq -0x8(%rbp), %rsi
callq 0x1a6f0
movl %eax, -0x44(%rbp)
movl -0x44(%rbp), %eax
movl $0x18, %ecx
cltd
idivl %ecx
movl %eax, -0x24(%rbp)
movl -0x44(%rbp), %eax
movl $0x18, %ecx
cltd
idivl %ecx
movl %edx, -0x30(%rbp)
movl -0x30(%rbp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
cmpl $0x3, %eax
jge 0x1b5e7
movl $0x1, -0x28(%rbp)
jmp 0x1b5ee
movl $0x3, -0x28(%rbp)
movl -0x30(%rbp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
movl %edx, -0x2c(%rbp)
movq -0x8(%rbp), %rdi
callq 0xa500
movsd 0x23a03(%rip), %xmm1    # 0x3f010
ucomisd %xmm1, %xmm0
jbe 0x1b645
movl -0x24(%rbp), %eax
movl %eax, -0x18(%rbp)
movl -0x28(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x30(%rbp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
movslq %eax, %rcx
leaq 0x32b56(%rip), %rax     # 0x4e190
movl (%rax,%rcx,4), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
jmp 0x1b6a1
movslq -0x2c(%rbp), %rcx
leaq 0x32b60(%rip), %rax     # 0x4e1b0
movl (%rax,%rcx,4), %eax
movl %eax, -0x18(%rbp)
movslq -0x28(%rbp), %rcx
leaq 0x32b4f(%rip), %rax     # 0x4e1b0
movl (%rax,%rcx,4), %eax
movl %eax, -0x1c(%rbp)
movslq -0x24(%rbp), %rcx
leaq 0x32b3e(%rip), %rax     # 0x4e1b0
movl (%rax,%rcx,4), %eax
movl %eax, -0x20(%rbp)
movl -0x30(%rbp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
movslq %eax, %rcx
leaq 0x32b03(%rip), %rax     # 0x4e190
movslq (%rax,%rcx,4), %rcx
leaq 0x32b18(%rip), %rax     # 0x4e1b0
movl (%rax,%rcx,4), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movl -0x18(%rbp), %eax
shll $0x4, %eax
movl -0x1c(%rbp), %ecx
shll $0x2, %ecx
addl %ecx, %eax
addl -0x20(%rbp), %eax
movl %eax, -0x38(%rbp)
movl -0x3c(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0x3c(%rbp)
imull $0x64, 0x32b15(%rip), %ecx # 0x4e1dc
cmpl %ecx, %eax
jle 0x1b6f4
movq 0x32926(%rip), %rax     # 0x4dff8
movq (%rax), %rdi
imull $0x64, 0x32b00(%rip), %edx # 0x4e1dc
leaq 0x25be9(%rip), %rsi     # 0x412cc
movb $0x0, %al
callq 0x21b0
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x2290
jmp 0x1b552
movq -0x58(%rbp), %rax
movslq -0x38(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
cmpl $0x1, 0x4(%rax)
jne 0x1b717
movl $0x0, -0x34(%rbp)
jmp 0x1b770
movq -0x58(%rbp), %rax
movslq -0x38(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
cmpl $0x1, 0x4(%rax)
jle 0x1b74c
movq -0x58(%rbp), %rax
movslq -0x38(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %edi
movq -0x8(%rbp), %rsi
callq 0x1ba30
movl %eax, -0x34(%rbp)
jmp 0x1b76e
movq 0x328a5(%rip), %rax     # 0x4dff8
movq (%rax), %rdi
leaq 0x25bd9(%rip), %rsi     # 0x41336
movb $0x0, %al
callq 0x21b0
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x2290
jmp 0x1b770
movq -0x58(%rbp), %rax
movslq -0x38(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movslq -0x34(%rbp), %rcx
movl (%rax,%rcx,4), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
movq -0x58(%rbp), %rdi
movslq -0x38(%rbp), %rax
shlq $0x4, %rax
addq %rax, %rdi
movl -0x34(%rbp), %esi
callq 0x1ba70
movl -0x48(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq