// File: /workspace/github_c_makefile_star2_O3/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 $0x48, %rsp
movq %rcx, %r15
movl %edx, 0x1c(%rsp)
movl %esi, %r13d
movq %rdi, 0x30(%rsp)
testl %edx, %edx
movl 0x206c0(%rip), %ebx     # 0x377a0
movl 0x206bd(%rip), %r12d    # 0x377a4
movl %r12d, %ebp
cmovel %ebx, %ebp
movq 0x204e4(%rip), %rcx     # 0x375d8
movq 0x204e5(%rip), %rax     # 0x375e0
movq %rcx, 0x40(%rsp)
cmoveq %rcx, %rax
movq %rax, 0x28(%rsp)
cmpb $0x1, 0x1f270(%rip)     # 0x36380
cvtsi2sd %ebp, %xmm0
movsd %xmm0, 0x38(%rsp)
jne 0x17131
movl 0x20685(%rip), %r14d    # 0x377a8
testl %r13d, %r13d
je 0x1718a
subl 0x20439(%rip), %r14d    # 0x37568
jmp 0x171a6
movsd 0x20467(%rip), %xmm1    # 0x375a0
mulsd %xmm0, %xmm1
movsd %xmm1, 0x20(%rsp)
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
xorpd %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x20(%rsp), %xmm0
movq %r15, %rdi
callq 0x1687f
movsd 0x8(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
movsd 0x8(%rsp), %xmm0
incl %r14d
movsd 0xbf7e(%rip), %xmm1     # 0x23100
ucomisd %xmm0, %xmm1
jae 0x1714d
jmp 0x171a6
movsd 0xbf86(%rip), %xmm0     # 0x23118
movl %r14d, %edi
movq %r15, %rsi
callq 0x1766c
movl %eax, %r14d
movl %eax, 0x203c2(%rip)     # 0x37568
movl 0x1c(%rsp), %ecx
testl %ecx, %ecx
movl %ebp, 0x10(%rsp)
je 0x171d5
movl 0x20430(%rip), %eax     # 0x375e8
addl %r14d, %eax
cmpl $0x1, %ecx
jne 0x171e6
addl %r12d, %r12d
movb $0x1, %cl
cmpl %r12d, %eax
jle 0x171e8
movl %r14d, %edi
movl %r12d, %esi
callq 0x5475
movl 0x2040d(%rip), %eax     # 0x375e8
addl %r14d, %eax
cmpl %ebx, %eax
jg 0x1743c
xorl %ecx, %ecx
movl %eax, 0x203fa(%rip)     # 0x375e8
movl %r14d, 0x18(%rsp)
testl %r14d, %r14d
jle 0x173dd
testl %r13d, %r13d
sete %bl
andb %cl, %bl
cmpl $0x1, %r13d
sete %al
andb %cl, %al
movb %al, 0x8(%rsp)
imull $0x64, 0x10(%rsp), %r12d
xorl %eax, %eax
xorl %r14d, %r14d
movl %r13d, 0x14(%rsp)
movl %eax, 0x20(%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), %r13
cmovgq %rdx, %r13
movq %r13, (%r15)
xorps %xmm0, %xmm0
cvtsi2sd %r13, %xmm0
divsd 0xbe9c(%rip), %xmm0     # 0x23120
mulsd 0x38(%rsp), %xmm0
callq 0x2270
movq 0x2032a(%rip), %rbp     # 0x375c0
cvttsd2si %xmm0, %eax
movl 0x1c(%rsp), %r8d
testl %r8d, %r8d
je 0x172f9
testb %bl, %bl
je 0x172cb
movslq %eax, %rcx
movq 0x28(%rsp), %rdx
movslq (%rdx,%rcx,4), %rcx
movq %rcx, %rdx
shlq $0x7, %rdx
leaq (%rdx,%rcx,8), %rcx
cmpl $0x0, 0x10(%rbp,%rcx)
jne 0x17317
jmp 0x17390
cmpb $0x0, 0x8(%rsp)
je 0x17390
movslq %eax, %rcx
movq 0x28(%rsp), %rdx
movslq (%rdx,%rcx,4), %rcx
movq %rcx, %rdx
shlq $0x7, %rdx
leaq (%rdx,%rcx,8), %rcx
cmpl $0x0, 0x14(%rbp,%rcx)
jne 0x17317
jmp 0x17390
movslq %eax, %rcx
movq 0x40(%rsp), %rdx
movslq (%rdx,%rcx,4), %rcx
movq %rcx, %rdx
shlq $0x7, %rdx
leaq (%rdx,%rcx,8), %rcx
cmpl $0x0, 0xc(%rbp,%rcx)
je 0x172a4
movq %r13, %rax
movabsq $0x41a705af1fe3fb79, %rcx # imm = 0x41A705AF1FE3FB79
imulq %rcx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0xf, %rdx
addq %rax, %rdx
imulq $0x1f31d, %rdx, %rax    # imm = 0x1F31D
subq %rax, %r13
imulq $0x41a7, %r13, %rax     # imm = 0x41A7
imulq $-0xb14, %rdx, %rcx     # imm = 0xF4EC
leaq (%rcx,%rax), %rdx
testq %rdx, %rdx
leaq 0x7fffffff(%rcx,%rax), %r13
cmovgq %rdx, %r13
movq %r13, (%r15)
xorps %xmm0, %xmm0
cvtsi2sd %r13, %xmm0
divsd 0xbdad(%rip), %xmm0     # 0x23120
mulsd 0x38(%rsp), %xmm0
callq 0x2270
leal 0x1(%r14), %eax
cmpl %r12d, %r14d
movl %eax, %r14d
jle 0x17296
jmp 0x173ec
cmpl $0x1, 0x1ee5d(%rip)     # 0x361f4
cltq
movq 0x28(%rsp), %rcx
movl (%rcx,%rax,4), %edx
jne 0x173b9
movq 0x30(%rsp), %rdi
movl 0x14(%rsp), %esi
movl %r8d, %ecx
movq %r15, %r8
callq 0x1788f
jmp 0x173cd
movq 0x30(%rsp), %rdi
movl 0x14(%rsp), %esi
movl %r8d, %ecx
movq %r15, %r8
callq 0x17b60
movl 0x20(%rsp), %eax
incl %eax
cmpl 0x18(%rsp), %eax
jne 0x17221
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x1ec05(%rip), %rbx     # 0x35ff8
movq (%rbx), %rdi
leaq 0xe216(%rip), %rsi      # 0x25613
movl %r12d, %edx
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rdi
leaq 0xe238(%rip), %rsi      # 0x25649
movl 0x18(%rsp), %edx
movl 0x20(%rsp), %ecx
xorl %eax, %eax
callq 0x21c0
movl 0x10(%rsp), %edi
testl %edi, %edi
jle 0x17432
movq 0x28(%rsp), %rsi
callq 0x5504
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x22a0
movl %r14d, %edi
callq 0x555d