// File: /workspace/github_c_makefile_star2_O2/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 $0x28, %rsp
movq %rcx, %r15
movl %edx, %r14d
movq %rdi, 0x18(%rsp)
testl %edx, %edx
movl 0x1de7e(%rip), %ebp     # 0x317a0
movl 0x1de7b(%rip), %r13d    # 0x317a4
movl %r13d, %ebx
cmovel %ebp, %ebx
movq 0x1dca2(%rip), %rax     # 0x315d8
movq 0x1dca3(%rip), %r12     # 0x315e0
movq %rax, 0x20(%rsp)
cmoveq %rax, %r12
cmpb $0x1, 0x1ca33(%rip)     # 0x30380
movl %esi, 0xc(%rsp)
jne 0x13965
movl 0x1de4f(%rip), %edi     # 0x317a8
testl %esi, %esi
je 0x1397d
subl 0x1dc05(%rip), %edi     # 0x31568
jmp 0x13995
cvtsi2sd %ebx, %xmm0
mulsd 0x1dc2f(%rip), %xmm0    # 0x315a0
movq %r15, %rdi
callq 0x13e90
movl %eax, %edi
jmp 0x13995
movsd 0xb743(%rip), %xmm0     # 0x1f0c8
movq %r15, %rsi
callq 0x13e47
movl %eax, %edi
movl %eax, 0x1dbd3(%rip)     # 0x31568
testl %r14d, %r14d
movl %edi, 0x8(%rsp)
je 0x139f4
movl 0x1dc44(%rip), %eax     # 0x315e8
addl %edi, %eax
cmpl $0x1, %r14d
jne 0x13a04
movl %r14d, %ebp
addl %r13d, %r13d
movb $0x1, %cl
cmpl %r13d, %eax
jle 0x13a09
movq 0x1c638(%rip), %r14     # 0x2fff8
movq (%r14), %rcx
leaq 0xdb62(%rip), %rdi      # 0x2152c
pushq $0x50
popq %rsi
pushq $0x1
popq %rbx
movq %rbx, %rdx
callq 0x22b0
movq (%r14), %rdi
movl 0x1dc07(%rip), %edx     # 0x315e8
leaq 0xd8e8(%rip), %rsi      # 0x212d0
movl 0x8(%rsp), %ecx
movl %r13d, %r8d
jmp 0x13be1
movl 0x1dbee(%rip), %eax     # 0x315e8
addl %edi, %eax
cmpl %ebp, %eax
jg 0x13ba7
movl %r14d, %ebp
xorl %ecx, %ecx
movl %eax, 0x1dbd9(%rip)     # 0x315e8
movl 0xc(%rsp), %eax
testl %eax, %eax
sete %dl
andb %cl, %dl
movb %dl, 0x7(%rsp)
cmpl $0x1, %eax
sete %al
andb %cl, %al
movb %al, 0x6(%rsp)
imull $0x64, %ebx, %r13d
xorl %r14d, %r14d
movl 0x8(%rsp), %eax
testl %eax, %eax
movl $0x0, %ecx
cmovgl %eax, %ecx
movl %ecx, 0x14(%rsp)
xorl %eax, %eax
cmpl 0x14(%rsp), %eax
je 0x13b98
movl %eax, 0x10(%rsp)
movl %ebx, %edi
movq %r15, %rsi
callq 0x14020
cltq
testl %ebp, %ebp
je 0x13aa7
cmpb $0x0, 0x7(%rsp)
je 0x13a85
movq 0x1db4f(%rip), %rcx     # 0x315c0
movslq (%r12,%rax,4), %rdx
imulq $0x88, %rdx, %rdx
cmpl $0x0, 0x10(%rcx,%rdx)
jne 0x13ac5
jmp 0x13add
cmpb $0x0, 0x6(%rsp)
je 0x13add
movq 0x1db2d(%rip), %rcx     # 0x315c0
movslq (%r12,%rax,4), %rdx
imulq $0x88, %rdx, %rdx
cmpl $0x0, 0x14(%rcx,%rdx)
jne 0x13ac5
jmp 0x13add
movq 0x1db12(%rip), %rcx     # 0x315c0
movq 0x20(%rsp), %rdx
movslq (%rdx,%rax,4), %rdx
imulq $0x88, %rdx, %rdx
cmpl $0x0, 0xc(%rcx,%rdx)
je 0x13a63
movl %ebx, %edi
movq %r15, %rsi
callq 0x14020
leal 0x1(%r14), %ecx
cmpl %r13d, %r14d
movl %ecx, %r14d
jle 0x13a5d
jmp 0x13b1d
cmpl $0x1, 0x1c710(%rip)     # 0x301f4
movl (%r12,%rax,4), %edx
jne 0x13aff
movq 0x18(%rsp), %rdi
movl 0xc(%rsp), %esi
movl %ebp, %ecx
movq %r15, %r8
callq 0x1403e
jmp 0x13b12
movq 0x18(%rsp), %rdi
movl 0xc(%rsp), %esi
movl %ebp, %ecx
movq %r15, %r8
callq 0x14286
movl 0x10(%rsp), %eax
incl %eax
jmp 0x13a45
movq 0x1c4d4(%rip), %r15     # 0x2fff8
movq (%r15), %rdi
leaq 0xda4f(%rip), %rsi      # 0x2157d
xorl %r14d, %r14d
movl %r13d, %edx
xorl %eax, %eax
callq 0x21c0
movq (%r15), %rdi
leaq 0xda6e(%rip), %rsi      # 0x215b3
movl 0x8(%rsp), %edx
movl 0x10(%rsp), %ecx
xorl %eax, %eax
callq 0x21c0
testl %ebx, %ebx
cmovlel %r14d, %ebx
leaq 0xda7c(%rip), %r14      # 0x215dd
xorl %r13d, %r13d
cmpq %r13, %rbx
je 0x13c27
movq (%r15), %rdi
movslq (%r12,%r13,4), %rax
leal 0x1(%rax), %edx
movq 0x1da42(%rip), %rcx     # 0x315c0
imulq $0x88, %rax, %rax
movl 0xc(%rcx,%rax), %ecx
movq %r14, %rsi
xorl %eax, %eax
callq 0x21c0
incq %r13
jmp 0x13b64
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %edi, %ebp
movq 0x1c448(%rip), %r14     # 0x2fff8
movq (%r14), %rcx
leaq 0xd6c5(%rip), %rdi      # 0x2127f
pushq $0x50
popq %rsi
pushq $0x1
popq %rbx
movq %rbx, %rdx
callq 0x22b0
movq (%r14), %rdi
movl 0x1da17(%rip), %edx     # 0x315e8
movl 0x1dbc8(%rip), %r8d     # 0x317a0
leaq 0xd6f1(%rip), %rsi      # 0x212d0
movl %ebp, %ecx
xorl %eax, %eax
callq 0x21c0
movq (%r14), %rcx
leaq 0xd737(%rip), %rdi      # 0x21329
pushq $0x3f
popq %rsi
movq %rbx, %rdx
callq 0x22b0
movq (%r14), %rcx
leaq 0xd762(%rip), %rdi      # 0x21369
pushq $0x3a
popq %rsi
movq %rbx, %rdx
callq 0x22b0
movq (%r14), %rcx
leaq 0xd788(%rip), %rdi      # 0x213a4
pushq $0x6b
popq %rsi
movq %rbx, %rdx
callq 0x22b0
pushq $-0x1
popq %rdi
callq 0x22a0