// File: /workspace/github_c_makefile_star2_O1/dapogon[P]cellcoal/src/cellcoal.c
// Function: SimulateISM
void SimulateISM (TreeNode *p, int genome, int doISMhaploid, long int *seed)
    {
    int		i, trials, numMutations, mutationsSoFar;
    double	totalBranchSum;
    int		*modelSites, numModelSites;

	if (doISMhaploid == NO)
		{
		modelSites = DefaultModelSites;
		numModelSites = numDefaultModelSites;
		}
	else
 		{
		modelSites = AltModelSites;
		numModelSites = numAltModelSites;
		}


	totalBranchSum = totalTreeLength * numModelSites;

    if (doSimulateFixedNumMutations == YES) /* conditioned on a specific 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 (doISMhaploid == NO && numISMmutations + numMutations > (numModelSites))
        {
        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);
        }
    else if (doISMhaploid == YES && numISMmutations + numMutations > (2*numModelSites))
        {
        fprintf (stderr, "\n\nERROR: The haploid 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, 2*numModelSites);
        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;
    trials = 0;
    mutationsSoFar = 0;
    while (mutationsSoFar < numMutations)
        {
        i = RandomUniformTo(numModelSites, seed);  /* choose a site at random */
        while (((doISMhaploid == NO)  && (allSites[modelSites[i]].numMutations != 0))  ||
               ((doISMhaploid == YES) && (genome == MATERNAL) && (allSites[modelSites[i]].numMutationsMaternal != 0)) ||
               ((doISMhaploid == YES) && (genome == PATERNAL) && (allSites[modelSites[i]].numMutationsPaternal != 0)))
            {
            i = RandomUniformTo(numModelSites, seed);
            if (trials++ > 100*numModelSites)
                {
                fprintf (stderr, "\n\n ERROR: after %d trials cannot find an unmuted site",100*numModelSites);
                fprintf (stderr, "\nmutations = %d   mutations so far = %d\n\n",numMutations, mutationsSoFar);
                for (i=0; i<numModelSites; i++)
                    fprintf (stderr, "\nsite %d has %d mutations",modelSites[i]+1, allSites[modelSites[i]].numMutations);
                exit(-1);
                }
            }
        if (alphabet == DNA)
            SimulateISMDNAforSite (p, genome, modelSites[i], doISMhaploid, seed);
        else
            SimulateISMforSite (p, genome, modelSites[i], doISMhaploid, seed);
			
        mutationsSoFar++;
			
        #ifdef MYDEBUG
            fprintf (stderr, "\nmutations = %d   mutations so far = %d\n",numMutations, mutationsSoFar);
            if (allSites[modelSites[i]].numMutations > 1)
                {
                fprintf (stderr, "\n\n ERROR: %d mutations in site %d",allSites[modelSites[i]].numMutations, modelSites[i]+1);
                exit(-1);
                }
            for (i=0; i<numDefaultModelSites; i++)
                fprintf (stderr, "%2d[%d] ",modelSites[i]+1, allSites[modelSites[i]].numMutations);
        #endif
			
        }
    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rcx, %r15
movl %edx, 0x4(%rsp)
movl %esi, %ebp
movq %rdi, 0x28(%rsp)
testl %edx, %edx
leaq 0x2c97e(%rip), %rax     # 0x437a0
leaq 0x2c97b(%rip), %rcx     # 0x437a4
cmoveq %rax, %rcx
movl (%rcx), %ebx
leaq 0x2c7a2(%rip), %rax     # 0x435d8
leaq 0x2c7a3(%rip), %rcx     # 0x435e0
cmoveq %rax, %rcx
movq (%rcx), %r14
cmpb $0x1, 0x2b535(%rip)     # 0x42380
cvtsi2sd %ebx, %xmm0
movsd %xmm0, 0x30(%rsp)
jne 0x16e6b
movl 0x2c94a(%rip), %r12d    # 0x437a8
testl %ebp, %ebp
je 0x16ec4
subl 0x2c6ff(%rip), %r12d    # 0x43568
jmp 0x16ee0
movsd 0x2c72d(%rip), %xmm1    # 0x435a0
mulsd %xmm0, %xmm1
movsd %xmm1, 0x18(%rsp)
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
xorpd %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x18(%rsp), %xmm0
movq %r15, %rdi
callq 0x165c5
movsd 0x8(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
movsd 0x8(%rsp), %xmm0
incl %r12d
movsd 0x1d14c(%rip), %xmm1    # 0x34008
ucomisd %xmm0, %xmm1
jae 0x16e87
jmp 0x16ee0
movsd 0x1d154(%rip), %xmm0    # 0x34020
movl %r12d, %edi
movq %r15, %rsi
callq 0x17391
movl %eax, %r12d
movl %eax, 0x2c688(%rip)     # 0x43568
movl 0x4(%rsp), %ecx
testl %ecx, %ecx
jne 0x16ef9
movl 0x2c6fa(%rip), %eax     # 0x435e8
addl %r12d, %eax
cmpl %ebx, %eax
jg 0x17152
cmpl $0x1, %ecx
jne 0x16f12
movl 0x2c6e4(%rip), %eax     # 0x435e8
addl %r12d, %eax
leal (%rbx,%rbx), %esi
cmpl %esi, %eax
jg 0x1714a
movq %rbx, 0x20(%rsp)
addl %r12d, 0x2c6ca(%rip)    # 0x435e8
movl %r12d, 0x14(%rsp)
testl %r12d, %r12d
jle 0x170ec
cmpl $0x1, 0x4(%rsp)
sete %al
testl %ebp, %ebp
sete %r13b
andb %al, %r13b
cmpl $0x1, %ebp
sete %cl
andb %al, %cl
movb %cl, 0x8(%rsp)
imull $0x64, 0x20(%rsp), %r12d
xorl %eax, %eax
xorl %ebx, %ebx
movl %ebp, 0x10(%rsp)
movl %eax, 0x18(%rsp)
movq (%r15), %rcx
movq %rcx, %rax
movabsq $0x41a705af1fe3fb79, %rdx # imm = 0x41A705AF1FE3FB79
imulq %rdx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0xf, %rdx
addq %rax, %rdx
imulq $0x1f31d, %rdx, %rax    # imm = 0x1F31D
subq %rax, %rcx
imulq $0x41a7, %rcx, %rax     # imm = 0x41A7
imulq $-0xb14, %rdx, %rcx     # imm = 0xF4EC
leaq (%rcx,%rax), %rdx
testq %rdx, %rdx
leaq 0x7fffffff(%rcx,%rax), %rax
cmovgq %rdx, %rax
movq %rax, (%r15)
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x1d06e(%rip), %xmm0    # 0x34028
mulsd 0x30(%rsp), %xmm0
callq 0x2270
movq 0x2c5f4(%rip), %rbp     # 0x435c0
cvttsd2si %xmm0, %eax
cltq
movl 0x4(%rsp), %ecx
testl %ecx, %ecx
je 0x1701b
testb %r13b, %r13b
je 0x16ff5
movslq (%r14,%rax,4), %rsi
movq %rsi, %rdx
shlq $0x7, %rdx
leaq (%rdx,%rsi,8), %rdx
cmpl $0x0, 0x10(%rbp,%rdx)
jne 0x17031
cmpb $0x0, 0x8(%rsp)
je 0x170ab
movslq (%r14,%rax,4), %rsi
movq %rsi, %rdx
shlq $0x7, %rdx
leaq (%rdx,%rsi,8), %rdx
cmpl $0x0, 0x14(%rbp,%rdx)
jne 0x17031
jmp 0x170ab
movslq (%r14,%rax,4), %rsi
movq %rsi, %rdx
shlq $0x7, %rdx
leaq (%rdx,%rsi,8), %rdx
cmpl $0x0, 0xc(%rbp,%rdx)
je 0x16fda
movq (%r15), %rcx
movq %rcx, %rax
movabsq $0x41a705af1fe3fb79, %rdx # imm = 0x41A705AF1FE3FB79
imulq %rdx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0xf, %rdx
addq %rax, %rdx
imulq $0x1f31d, %rdx, %rax    # imm = 0x1F31D
subq %rax, %rcx
imulq $0x41a7, %rcx, %rax     # imm = 0x41A7
imulq $-0xb14, %rdx, %rcx     # imm = 0xF4EC
leaq (%rcx,%rax), %rdx
testq %rdx, %rdx
leaq 0x7fffffff(%rcx,%rax), %rax
cmovgq %rdx, %rax
movq %rax, (%r15)
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x1cf98(%rip), %xmm0    # 0x34028
mulsd 0x30(%rsp), %xmm0
callq 0x2270
leal 0x1(%rbx), %eax
cmpl %r12d, %ebx
movl %eax, %ebx
jle 0x16fcc
jmp 0x170fb
cmpl $0x1, 0x2b142(%rip)     # 0x421f4
movl (%r14,%rax,4), %edx
jne 0x170cb
movq 0x28(%rsp), %rdi
movl 0x10(%rsp), %esi
movq %r15, %r8
callq 0x1758d
jmp 0x170dc
movq 0x28(%rsp), %rdi
movl 0x10(%rsp), %esi
movq %r15, %r8
callq 0x17811
movl 0x18(%rsp), %eax
incl %eax
cmpl 0x14(%rsp), %eax
jne 0x16f57
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x2aef6(%rip), %rbx     # 0x41ff8
movq (%rbx), %rdi
leaq 0x1f447(%rip), %rsi     # 0x36553
movl %r12d, %edx
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rdi
leaq 0x1f469(%rip), %rsi     # 0x36589
movl 0x14(%rsp), %edx
movl 0x18(%rsp), %ecx
xorl %eax, %eax
callq 0x21c0
movq 0x20(%rsp), %rdi
testl %edi, %edi
jle 0x17140
movq %r14, %rsi
callq 0x546c
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x22a0
movl %r12d, %edi
callq 0x54c5
movl %r12d, %edi
callq 0x5554