// File: /workspace/github_c_makefile_star2_O0/dapogon[P]cellcoal/src/cellcoal.c
// Function: SimulateSignatureISM
void SimulateSignatureISM (TreeNode *p, int genome, long int *seed)
    {
    int		i, numMutations, mutationsSoFar;
    double	totalBranchSum;
	int		newState, chosenSite;
	
	newState = -9;
	
	/* allocate memory to store the trinucleotide frequencies */
	triNucleotideMaternal = (TriNucStr *) calloc (64, sizeof(TriNucStr));
	if (!triNucleotideMaternal)
		{
		fprintf (stderr, "Could not allocate the triNucleotideMaternal vector\n");
		exit (-1);
		}
	for (i=0; i<64; i++)
		{
		triNucleotideMaternal[i].tempLength = 100;
		triNucleotideMaternal[i].numAvailablePositions = 0;
		triNucleotideMaternal[i].position = (int *) calloc(100,sizeof(int));
		}

	triNucleotidePaternal = (TriNucStr *) calloc (64, sizeof(TriNucStr));
	if (!triNucleotidePaternal)
		{
		fprintf (stderr, "Could not allocate the triNucleotidePaternal vector\n");
		exit (-1);
		}
	for (i=0; i<64; i++)
		{
		triNucleotidePaternal[i].tempLength = 100;
		triNucleotidePaternal[i].numAvailablePositions = 0;
		triNucleotidePaternal[i].position = (int *) calloc(100,sizeof(int));
		}

	/* count trinucleotide frequencies in the healthy root genome */
	CountTriNucFrequencies (data[genome][OUTGROUP_ROOT], genome);

	totalBranchSum = totalTreeLength * numSites;

    if (doSimulateFixedNumMutations == YES) /* conditioned on a specified number of mutations */
		{
        if (genome == MATERNAL)
			 numMutations = numSNVmaternal =  RandomBinomial (0.5, numFixedMutations, seed);
        else
            numMutations = numFixedMutations - numSNVmaternal;
        }
    else
        numMutations = RandomPoisson (totalBranchSum, seed); /* the number of mutations will be distributed as a Poisson with parameter totalBranchSum */
		
     /* if the number of ISM mutations is bigger than the number of ISM sites quit the program and warn the user about violation of ISM */
     if ((numISMmutations + numMutations) > numSites)
        {
        fprintf (stderr, "\n\nERROR: The diploid infinite sites model (ISM) has been violated. There will be");
        fprintf (stderr, "\nmore mutations (%d existing + %d proposed]) than available sites under this model (%d).", numISMmutations, numMutations, numDefaultModelSites);
        fprintf (stderr, "\nTry using a smaller mutation rate or effective population size");
        fprintf (stderr, "\n(i.e. smaller theta) or check the proportion of JC sites.");
        fprintf (stderr, "\nIf using an user tree, try with smaller branch lengths (including the transforming and healthy branches).\n");
        exit (-1);
        }

	numISMmutations += numMutations;

	#ifdef PRINT_TRIMUTCOUNTER
	if (genome == MATERNAL)
		{
		triMutationsCounter = (int *) calloc (96, sizeof(int));
		if (!triMutationsCounter)
			{
			fprintf (stderr, "Could not allocate the triMutationsCounter vector\n");
			exit (-1);
			}
		}
	#endif

    mutationsSoFar = 0;
    while (mutationsSoFar < numMutations)
        {
 		chosenSite = ChooseTrinucleotideSite(seed, &newState, genome);
		
		if (allSites[chosenSite].numMutations == 0) /* force ISM diploid */
			{
			SimulateSignatureISMforSite (p, genome, chosenSite, newState, seed);
			mutationsSoFar++;
			}
		else // chose another site as this site has already changed in the maternal chromosome
			{
			//fprintf (stderr, "\nsite %d has already changed", chosenSite+1);
			}
        }
	
	//fprintf (stderr, "\n\nnumISMmutations = %d  numMutations = %d   mutationsSoFar = %d (genome = %d)",numISMmutations, numMutations, mutationsSoFar, genome);
	
	#ifdef PRINT_TRIMUTCOUNTER
	int j, k;
	int doDeconstructSigs = YES;
	FILE *fpCounts, *fpRefGenome;

	sprintf(File,"%s/%s", resultsDir, "trimutcounts");
	if ((fpCounts = fopen(File, "w")) == NULL)
		{
		fprintf (stderr, "Can't open \"%s\"\n", File);
		exit(-1);
		}

	if (doDeconstructSigs == NO) /* counter for SomaticSignatures */
		{
		for (i=0; i<96; i++)
			fprintf (fpCounts, "%d\n", triMutationsCounter[i]);
		}
	else /* counter for deconstructSigs */
		{
		for (j=0; j<6; j++)
			for (i=0; i<4; i++)
				for (k=0; k<4; k++)
					fprintf (fpCounts, "%d\n", triMutationsCounter[trimut(i,j,k)]);
		}
	fclose(fpCounts);

	/* print reference genome as genome context for SomaticSignatures */
	sprintf(File,"%s/%s", resultsDir, "contextGenome");
	if ((fpRefGenome = fopen(File, "w")) == NULL)
		{
		fprintf (stderr, "Can't open \"%s\"\n", File);
		exit(-1);
		}
	fprintf (fpRefGenome, ">1\n");
	for (i=0; i<numSites; i++)
		fprintf (fpRefGenome, "%c", WhichNuc(allSites[i].referenceAllele));
	fclose(fpRefGenome);
	#endif
		
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movl $0xfffffff7, -0x34(%rbp) # imm = 0xFFFFFFF7
movl $0x40, %edi
movl $0x10, %esi
callq 0x2190
movq %rax, 0x350d8(%rip)     # 0x4f868
cmpq $0x0, 0x350d0(%rip)     # 0x4f868
jne 0x1a7bc
movq 0x33857(%rip), %rax     # 0x4dff8
movq (%rax), %rdi
leaq 0x268e7(%rip), %rsi     # 0x41092
movb $0x0, %al
callq 0x21b0
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x2290
movl $0x0, -0x1c(%rbp)
cmpl $0x40, -0x1c(%rbp)
jge 0x1a82d
movq 0x35098(%rip), %rax     # 0x4f868
movslq -0x1c(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl $0x64, (%rax)
movq 0x35080(%rip), %rax     # 0x4f868
movslq -0x1c(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl $0x0, 0x4(%rax)
movl $0x64, %edi
movl $0x4, %esi
callq 0x2190
movq %rax, %rcx
movq 0x35055(%rip), %rax     # 0x4f868
movslq -0x1c(%rbp), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x1a7c3
movl $0x40, %edi
movl $0x10, %esi
callq 0x2190
movq %rax, 0x3502d(%rip)     # 0x4f870
cmpq $0x0, 0x35025(%rip)     # 0x4f870
jne 0x1a86f
movq 0x337a4(%rip), %rax     # 0x4dff8
movq (%rax), %rdi
leaq 0x26869(%rip), %rsi     # 0x410c7
movb $0x0, %al
callq 0x21b0
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x2290
movl $0x0, -0x1c(%rbp)
cmpl $0x40, -0x1c(%rbp)
jge 0x1a8e0
movq 0x34fed(%rip), %rax     # 0x4f870
movslq -0x1c(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl $0x64, (%rax)
movq 0x34fd5(%rip), %rax     # 0x4f870
movslq -0x1c(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl $0x0, 0x4(%rax)
movl $0x64, %edi
movl $0x4, %esi
callq 0x2190
movq %rax, %rcx
movq 0x34faa(%rip), %rax     # 0x4f870
movslq -0x1c(%rbp), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x1a876
movq 0x34eb9(%rip), %rax     # 0x4f7a0
movslq -0xc(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0x34e4a(%rip), %rcx     # 0x4f740
movq (%rax,%rcx,8), %rdi
movl -0xc(%rbp), %esi
callq 0x1b260
movsd 0x34e7e(%rip), %xmm0    # 0x4f788
cvtsi2sdl 0x338ca(%rip), %xmm1 # 0x4e1dc
mulsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rbp)
cmpl $0x1, 0x33a9e(%rip)     # 0x4e3c0
jne 0x1a95d
cmpl $0x0, -0xc(%rbp)
jne 0x1a94c
movl 0x350a0(%rip), %edi     # 0x4f9d0
movq -0x18(%rbp), %rsi
movsd 0x246d4(%rip), %xmm0    # 0x3f010
callq 0x1b310
movl %eax, 0x34e01(%rip)     # 0x4f748
movl %eax, -0x20(%rbp)
jmp 0x1a95b
movl 0x3507e(%rip), %eax     # 0x4f9d0
subl 0x34df0(%rip), %eax     # 0x4f748
movl %eax, -0x20(%rbp)
jmp 0x1a96e
movsd -0x30(%rbp), %xmm0
movq -0x18(%rbp), %rdi
callq 0x1b370
movl %eax, -0x20(%rbp)
movl 0x34e5c(%rip), %eax     # 0x4f7d0
addl -0x20(%rbp), %eax
cmpl 0x3385f(%rip), %eax     # 0x4e1dc
jle 0x1aa15
movq 0x3366e(%rip), %rax     # 0x4dff8
movq (%rax), %rdi
leaq 0x26768(%rip), %rsi     # 0x410fc
movb $0x0, %al
callq 0x21b0
movq 0x33656(%rip), %rax     # 0x4dff8
movq (%rax), %rdi
movl 0x34e25(%rip), %edx     # 0x4f7d0
movl -0x20(%rbp), %ecx
movl 0x35013(%rip), %r8d     # 0x4f9c8
leaq 0x26791(%rip), %rsi     # 0x4114d
movb $0x0, %al
callq 0x21b0
movq 0x3362e(%rip), %rax     # 0x4dff8
movq (%rax), %rdi
leaq 0x267d2(%rip), %rsi     # 0x411a6
movb $0x0, %al
callq 0x21b0
movq 0x33616(%rip), %rax     # 0x4dff8
movq (%rax), %rdi
leaq 0x267fa(%rip), %rsi     # 0x411e6
movb $0x0, %al
callq 0x21b0
movq 0x335fe(%rip), %rax     # 0x4dff8
movq (%rax), %rdi
leaq 0x2681d(%rip), %rsi     # 0x41221
movb $0x0, %al
callq 0x21b0
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x2290
movl -0x20(%rbp), %eax
addl 0x34db2(%rip), %eax     # 0x4f7d0
movl %eax, 0x34dac(%rip)     # 0x4f7d0
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
cmpl -0x20(%rbp), %eax
jge 0x1aa86
movq -0x18(%rbp), %rdi
movl -0xc(%rbp), %edx
leaq -0x34(%rbp), %rsi
callq 0x1b3d0
movl %eax, -0x38(%rbp)
movq 0x34d5b(%rip), %rax     # 0x4f7a8
movslq -0x38(%rbp), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
cmpl $0x0, 0xc(%rax)
jne 0x1aa82
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x38(%rbp), %edx
movl -0x34(%rbp), %ecx
movq -0x18(%rbp), %r8
callq 0x1b7b0
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x1aa84
jmp 0x1aa84
jmp 0x1aa2b
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)