1 #ifndef DROP_INCLUDE
2 #include "jdrop.h"
3 #endif
4 
5 #ifdef DMEMDEBUG
6 #define MEMDEBUG
7 #include "memdebug.h"
8 #endif
9 
10 #ifdef DMALLOC_FUNC_CHECK
11 #include "/usr/local/include/dmalloc.h"
12 #endif
13 
14 extern tree *curtree;
15 extern double theta0, rec0;
16 extern long population, locus;
17 extern FILE *simlog;
18 
19 extern boolean istip(node *p);
20 extern node *otherparent(node *p);
21 extern void fixlength(option_struct *op, data_fmt *data, node *p);
22 extern void ltov(option_struct *op, data_fmt *data, node *p);
23 extern boolean branchsub(tlist *t, node *oldbranch, node *newbranch);
24 extern void init_ranges_alloc(long **ranges, long numranges);
25 extern boolean testratio(option_struct *op, data_fmt *data, tree
26    *oldtree, tree *newtree, char ratiotype);
27 extern void ranges_Malloc(node *p, boolean allokate, long numrangepairs);
28 extern void subtymelist(tlist *t, node *branch, boolean all);
29 extern double getdata_space(option_struct *op, data_fmt *data,
30    long target);
31 extern long countrbanches(option_struct *op, data_fmt *data,
32    tree *tr);
33 extern void localeval(option_struct *op, data_fmt *data, node *p,
34    boolean first);
35 extern void scoretree(option_struct *op, data_fmt *data, long chain);
36 extern double coalprob(option_struct *op, data_fmt *data, tree *tr,
37    double theta, double r);
38 
39 extern long locus; /* which locus are we currently working on? */
40 extern long numdropped; /* how many trees are dropped due to excessive
41                            amounts of recombination */
42 extern long indecks, apps; /* what step and chain are we on? */
43 /* This file contains all the functions involved in modifying the
44 tree */
45 
46 
countsites(option_struct * op,data_fmt * data)47 long countsites(option_struct *op, data_fmt *data)
48 {
49 long nummarkers;
50 
51 nummarkers = getdata_nummarkers(op,data);
52 
53 switch(op->datatype) {
54    case 'a':
55       break;
56    case 'b':
57    case 'm':
58       break;
59    case 'n':
60       return(data->dnaptr->sitecount[locus][nummarkers-1]);
61       break;
62    case 's':
63       return(nummarkers);
64       break;
65    default:
66       fprintf(ERRFILE,"countsites, found an unknown datatype %c\n",
67          op->datatype);
68       break;
69 }
70 
71 return(FLAGLONG);
72 
73 } /* countsites */
74 
75 
rename_branch(tlist * start,node * newbranch,node * oldbranch)76 void rename_branch(tlist *start, node *newbranch, node *oldbranch)
77 {
78 tlist *t;
79 boolean found;
80 
81 if (!newbranch) return;
82 
83 found = TRUE;
84 for(t = start; found && t != NULL; t = t->succ)
85    found = branchsub(t,oldbranch,newbranch);
86 
87 } /* rename_branch */
88 
89 
remove_branch(tlist * start,node * target)90 void remove_branch(tlist *start, node *target)
91 {
92 long i, j;
93 node *p;
94 tlist *t;
95 boolean found;
96 
97 if (!target) return;
98 
99 if(!target->top) p = target->back;
100 else p = target;
101 
102 for(t = start, found = TRUE; t != NULL && found; t = t->succ) {
103    found = FALSE;
104    for(i = 0; i < t->numbranch && !found; i++) {
105       if(t->branchlist[i] == p) {
106           t->numbranch--;
107           for(j = i; j < t->numbranch; j++)
108              t->branchlist[j] = t->branchlist[j+1];
109           found = TRUE;
110       }
111    }
112 }
113 
114 } /* remove_branch */
115 
116 
117 /* OBSOLETE */
118 /*********************************************************************
119  * subtymenode removes the tymenode containing the node "p" from the *
120  * tymelist.  The branch pointed to by the nodelet "p" will be       *
121  * completely erased from the branchlist.                            */
subtymenode(tree * tr,node * p)122 void subtymenode(tree *tr, node *p)
123 {
124 tlist *t;
125 node *q, *r;
126 
127 t = gettymenode(tr,p->number);
128 
129 q = findunique(p);
130 for(r = q->next; r == p; r = r->next) ;
131 if (isrecomb(p)) rename_branch(t,q->back,r);
132 else rename_branch(t,r->back,q);
133 remove_branch(t,p);
134 
135 } /* subtymenode */
136 
137 
138 /********************************************************************
139  * fix_treenodep() needs to called everytime a node is removed from *
140  * the tree.  "Number" is the number of the node to be removed.     *
141  * fix_treenodep assumes that the field  containing the number of   *
142  * coalescences is correct.                                         */
fix_treenodep(tree * tr,long number)143 void fix_treenodep(tree *tr, long number)
144 {
145 long i, numnodes;
146 
147 numnodes = 2 * tr->numcoals + 2; /* strange but true! */
148 for(i = number; i < numnodes-1; i++) tr->nodep[i] = tr->nodep[i + 1];
149 
150 } /* fix_treenodep */
151 
152 
isdead(option_struct * op,node * p)153 boolean isdead(option_struct *op, node *p)
154 {
155 
156 if (op->fc) return(!p->coal[0]);
157 else return(!p->ranges[0]);
158 
159 } /* isdead */
160 
161 
findpaired_coalnode(option_struct * op,node * p)162 node *findpaired_coalnode(option_struct *op, node *p)
163 {
164 
165 if (istip(p)) {
166    fprintf(ERRFILE,"ERROR:findpaired_coalnode found a tip!\n");
167    exit(-1);
168 }
169 
170 if (!isrecomb(p)) return(p);
171 
172 printf("ERROR:Shouldn't be here in findpaired_coalnode!\n");
173 if (isdead(op,p->next)) findpaired_coalnode(op,p->next->back);
174 else if (isdead(op,p->next->next))
175         findpaired_coalnode(op,p->next->next->back);
176      else {fprintf(ERRFILE,"ERROR:findpaired_coalnode failed!\n"); exit(-1);}
177 
178 fprintf(ERRFILE,"ERROR:findpaired_coalnode failure.  %ld %ld\n",indecks,apps);
179 return(NULL);
180 
181 } /* findpaired_coalnode */
182 
183 
184 /**********************************************************************
185  * remove_pairedcoalnode removes node "p" from tree "tr", and assumes *
186  * that the branch to be removed is the one which has it's bottom at  *
187  * the specific nodelet pointed to by "p".                            */
remove_pairedcoalnode(option_struct * op,data_fmt * data,tree * tr,node * p)188 void remove_pairedcoalnode(option_struct *op, data_fmt *data,
189    tree *tr, node *p)
190 {
191 tlist *t;
192 node *q;
193 
194 tr->numcoals--;
195 
196 hookup(p->next->next->back,p->next->back);
197 fixlength(op,data,p->next->back);
198 fix_treenodep(tr,p->number);
199 
200 t = gettymenode(tr,p->number);
201 q = (p->next->top) ? p->next->next->back : p->next->back;
202 subtymelist(t,q,FALSE);
203 freenode(p);
204 } /* remove_pairedcoalnode */
205 
206 
207 /****************************************************************
208  * remove_pairedrecombnode removes node "p" from tree "tr", and *
209  * assumes that "p" points to the unique nodelet of the         *
210  * recombination node.                                          */
remove_pairedrecombnode(option_struct * op,data_fmt * data,tree * tr,node * p,node * dead)211 void remove_pairedrecombnode(option_struct *op, data_fmt *data,
212    tree *tr, node *p, node *dead)
213 {
214 node *q;
215 tlist *t;
216 
217 tr->numrecombs--;
218 
219 for(q = p->next; q == dead; q = q->next) ;
220 hookup(p->back,q->back);
221 fixlength(op,data,p->back);
222 fix_treenodep(tr,p->number);
223 
224 t = gettymenode(tr,p->number);
225 subtymelist(t,dead,FALSE);
226 freenode(p);
227 } /* remove_pairedrecombnode */
228 
229 
remove_pairednodes(option_struct * op,data_fmt * data,tree * tr,node * p,node * remove_thisway)230 void remove_pairednodes(option_struct *op, data_fmt *data, tree *tr,
231    node *p, node *remove_thisway)
232 {
233 node *q;
234 
235 if (!remove_thisway->top) {
236    fprintf(ERRFILE,"ERROR:remove_pairednodes passed a non-top!\n");
237    exit(-1);
238 }
239 q = findpaired_coalnode(op,remove_thisway->back);
240 remove_pairedcoalnode(op,data,tr,q);
241 remove_pairedrecombnode(op,data,tr,p,remove_thisway);
242 
243 } /* remove_pairednodes */
244 
245 
setnodenumber(boolean ** nodenumber,long * numnodes)246 long setnodenumber(boolean **nodenumber, long *numnodes)
247 {
248 long i;
249 
250 for (i = 0; i < (*numnodes); i++)
251    if (!(*nodenumber)[i]) {
252       (*nodenumber)[i] = TRUE;
253       return(i);
254    }
255 
256 (*numnodes)++;
257 *nodenumber = (boolean *)realloc(*nodenumber,(*numnodes)*sizeof(boolean));
258 (*nodenumber)[(*numnodes) - 1] = TRUE;
259 
260 curtree->nodep = (node **)
261    realloc(curtree->nodep,((*numnodes)+1)*sizeof(node *));
262 
263 return((*numnodes) - 1);
264 
265 } /*setnodenumber */
266 
foundbranch(tlist * t,node * p)267 boolean foundbranch(tlist *t, node *p)
268 {
269 long i;
270 
271 for(i = 0; i < t->numbranch; i++)
272    if (t->branchlist[i] == p) return(TRUE);
273 
274 return(FALSE);
275 
276 } /* foundbranch */
277 
readdactive(tlist * stop,node * p)278 void readdactive(tlist *stop, node *p)
279 {
280 long i, j;
281 tlist *t;
282 
283 t = gettymenode(curtree,p->number);
284 do {
285    if (!foundbranch(t,p)) {
286       t->numbranch++;
287       t->branchlist =
288       (node **)realloc(t->branchlist, t->numbranch*sizeof(node *));
289       t->branchlist[t->numbranch-1] = p;
290    }
291    t = t->succ;
292 } while (t != stop && t != NULL);
293 
294 /* remove the FALSE branchlist entry from the rest of the tymelist */
295 while (t != NULL) {
296    if (!foundbranch(t,p)) break;
297    for (i = 0; i < t->numbranch; i++)
298       if (t->branchlist[i] == p) break;
299    for (j = i; j < t->numbranch - 1; j++)
300       t->branchlist[j] = t->branchlist[j+1];
301    t->numbranch--;
302    t = t->succ;
303 }
304 
305 } /* readdactive */
306 
newlin(linlist ** t)307 void newlin(linlist **t)
308 {
309   *t = (linlist *)(calloc(1,sizeof(linlist)));
310   (*t)->prev = NULL;
311   (*t)->succ = NULL;
312 } /* newlin */
313 
freelin(linlist * t)314 void freelin(linlist *t)
315 {
316   free(t);
317 } /* freelin */
318 
319 
freelinlist(linlist * t)320 void freelinlist(linlist *t)
321 {
322 linlist *u, *usucc;
323 
324 for(u = t; u != NULL; u = usucc) {usucc = u->succ; freelin(u);}
325 
326 } /* freelinlist */
327 
328 
addlinlist(linlist ** t,node * target,double activelinks)329 void addlinlist(linlist **t, node *target, double activelinks)
330 {
331   linlist *r, *s, *u;
332 
333   s = *t;
334   if (s == NULL) {
335     newlin(&s);
336     s->branchtop = target;
337     s->activesites = activelinks;
338     s->succ = NULL;
339     s->prev = NULL;
340     (*t)=s;
341   } else {
342     newlin(&r);
343     r->branchtop = target;
344     r->activesites = activelinks;
345     /* insert new entry right after s */
346     u = s->succ;
347     s->succ = r;
348     r->prev = s;
349     r->succ = u;
350     if(u!=NULL) u->prev = r;
351   }
352 } /* addlinlist */
353 
354 
sublinlist(linlist ** t,node * target)355 void sublinlist(linlist **t, node *target)
356 {
357   boolean found;
358   linlist *u;
359 
360   u = *t;
361   found = FALSE;
362   while (!found) {
363     if (u->branchtop==target) {
364       found = TRUE;
365       if (u->succ != NULL) u->succ->prev = u->prev;
366       if (u->prev != NULL) u->prev->succ = u->succ;
367       /* if this was the first entry, reset the lineage pointer */
368       if (u==(*t)) *t = u->succ;
369       freelin(u);
370     } else if (u->succ != NULL) u = u->succ;
371     else fprintf(ERRFILE, "ERROR:SUBLINLIST failed to find target\n");
372   }
373 } /* sublinlist */
374 
375 
376 /******************************************************
377  * printlinlist() prints a linlist:  a debug function */
printlinlist(linlist * u)378 void printlinlist(linlist *u)
379 {
380 if (u) {
381    do {
382      if(u->branchtop!=NULL)
383        fprintf(ERRFILE,"Branchtop %ld activesites %g\n",u->branchtop->number,
384        u->activesites);
385      else fprintf(ERRFILE,"This entry has no branchtop!\n");
386      u=u->succ;
387    } while (u!=NULL);
388 }
389 
390 }  /* printlinlist */
391 
392 
393 /***************************************************************
394  * foundlin() finds whether a given nodelet is already present *
395  * in the passed linlist.  TRUE = found, FALSE = not found.    */
foundlin(linlist * u,node * p)396 boolean foundlin(linlist *u, node *p)
397 {
398 for(;u != NULL; u = u->succ)
399    if(u->branchtop == p) return (TRUE);
400 
401 return(FALSE);
402 
403 } /* foundlin */
404 
405 
findlin(linlist ** u,long which)406 void findlin(linlist **u, long which)
407 {
408   long i;
409 
410   i = 1;
411   do {
412     if (i==which) return;
413     (*u) = (*u)->succ;
414     i++;
415   } while ((*u)!=NULL);
416   printf("ERROR:Unable to find linlist entry!\n");
417 } /* findlin */
418 
419 
420 /************************************************************************
421  * getnumlinks() returns the number of links between the passed "sites" */
getnumlinks(option_struct * op,data_fmt * data,long start,long end)422 double getnumlinks(option_struct *op, data_fmt *data, long start, long end)
423 {
424 long i;
425 double sum, *spaces;
426 
427 spaces = NULL;
428 
429 switch(op->datatype) {
430    case 'a':
431       break;
432    case 'b':
433    case 'm':
434       spaces = data->msptr->mspace[population][locus];
435       break;
436    case 'n':
437       return((double)(end - start));
438       break;
439    case 's':
440       spaces = data->dnaptr->sspace[population][locus];
441       for(i = start, sum = 0.0; i < end; i++)
442          sum += spaces[i];
443       return(sum);
444       break;
445    default:
446       fprintf(ERRFILE,"unknown datatype in getnumlinks\n");
447       break;
448 }
449 
450 return((double)FLAGLONG);
451 
452 } /* getnumlinks */
453 
454 
455 /*******************************************************************
456  * count_active() counts the number of active links leaving a node */
count_active(option_struct * op,data_fmt * data,node * p)457 double count_active(option_struct *op, data_fmt *data, node *p)
458 {
459 double value;
460 node *q;
461 
462 q = p;
463 if (!q->top) q = q->back;
464 
465 if (istip(q))
466 return(getnumlinks(op,data,0L,countsites(op,data)-1));
467 
468 if (isrecomb(q)) value = count_rec_active(op,data,q);
469 else value = count_coal_active(op,data,q);
470 
471 return(value);
472 
473 } /* count_active */
474 
475 
476 /*********************************************************************
477  * count_coal_active() returns the number of active links along the  *
478  * branch "p", where the node containing "p" must be coalescent; and *
479  * the branch "p" may not exist yet.                                 */
count_coal_active(option_struct * op,data_fmt * data,node * p)480 double count_coal_active(option_struct *op, data_fmt *data, node *p)
481 {
482 long *range1, *range2, newstart, newend;
483 
484 range1 = p->next->back->ranges;
485 range2 = p->next->next->back->ranges;
486 
487 if (!range1[0] && !range2[0])
488    fprintf(ERRFILE, "ERROR:Dead branch in count_coal_active! %ld %ld\n",
489       indecks,apps);
490 
491 if (!range1[0]) return(range2[2*range2[0]] - range2[1]);
492 if (!range2[0]) return(range1[2*range1[0]] - range1[1]);
493 
494 newstart = (range1[1] < range2[1]) ? range1[1] : range2[1];
495 newend = (range1[2*range1[0]] > range2[2*range2[0]]) ?
496             range1[2*range1[0]] : range2[2*range2[0]];
497 
498 if (newend - newstart < 0)
499    fprintf(ERRFILE,"ERROR:negative link count in count_coal_active! %ld %ld\n",
500       indecks,apps);
501 
502 return(getnumlinks(op,data,newstart,newend));
503 
504 } /* count_coal_active */
505 
506 
507 /*******************************************************************
508  * count_rec_active() returns the number of active links along the *
509  * branch "p", where the node containing "p" must be recombinant;  *
510  * and the branch "p" may not exist yet.                           */
count_rec_active(option_struct * op,data_fmt * data,node * p)511 double count_rec_active(option_struct *op, data_fmt *data, node *p)
512 {
513 long i, newstart, newend;
514 node *q;
515 
516 q = findunique(p)->back;
517 
518 if (!q->ranges[0])
519    fprintf(ERRFILE,"ERROR:count_rec_active counted dead, %ld %ld\n",
520       indecks,apps);
521 
522 for(i = 1, newstart = -1L; q->ranges[i] != FLAGLONG; i+=2) {
523    if(p->recstart > q->ranges[i+1]) continue;
524    newstart = (q->ranges[i] > p->recstart) ? q->ranges[i] : p->recstart;
525    break;
526 }
527 
528 if(newstart == -1L) return(0L);
529 
530 for(i=2*q->ranges[0], newend = -1L; i != 0; i-=2) {
531    if(p->recend < q->ranges[i-1]) continue;
532    newend = (q->ranges[i] < p->recend) ? q->ranges[i] : p->recend;
533    break;
534 }
535 
536 if(newend == -1L) return(0L);
537 
538 if (newend - newstart < 0)
539    fprintf(ERRFILE,"ERROR:negative link count in count_rec_active! %ld %ld\n",
540       indecks,apps);
541 
542 return(getnumlinks(op,data,newstart,newend));
543 
544 } /* count_rec_active */
545 
546 
547 /*********************************************************************
548  * count_activefc() counts the number of active links leaving a node *
549  * taking into account which sites have achieved final coalescence.  */
count_activefc(option_struct * op,data_fmt * data,node * p)550 double count_activefc(option_struct *op, data_fmt *data, node *p)
551 {
552 double value;
553 node *q;
554 
555 q = p;
556 if (!q->top) q = q->back;
557 
558 if (istip(q))
559    return(getnumlinks(op,data,0L,countsites(op,data)-1));
560 
561 if (op->datatype == 'n')
562    value = ((q->coal[0]) ? q->coal[2*q->coal[0]] - q->coal[1] : 0L);
563 else
564    value = ((q->coal[0]) ?
565    getnumlinks(op,data,q->coal[1],q->coal[2*q->coal[0]]) : 0L);
566 
567 return(value);
568 
569 } /* count_activefc */
570 
571 
572 /******************************************************************
573  * is_fc() returns TRUE if site has achieved fc by treesec, FALSE *
574  * otherwise.                                                     */
is_fc(tlist * treesec,long site)575 boolean is_fc(tlist *treesec, long site)
576 {
577 long i, count;
578 
579 for(i = 0, count = 0; i < treesec->numbranch; i++) {
580    if(inrange(treesec->branchlist[i]->ranges,site)) count++;
581    if (count > 1) return(FALSE);
582 }
583 
584 return(TRUE);
585 
586 } /* is_fc */
587 
588 
589 /***********************************************************
590  * fix_coal() upodates the coal array for the passed node. *
591  * "tfc" is the tymeslice used for FC calculations and all *
592  * tipwards tymeslices plus their eventnode's coal arrays  *
593  * are assumed to be correct.                              */
fix_coal(option_struct * op,data_fmt * data,tree * tr,tlist * tfc,node * p)594 void fix_coal(option_struct *op, data_fmt *data, tree *tr, tlist *tfc,
595   node *p)
596 {
597 long *subtrees;
598 node *q, *r, *s;
599 
600 if (isrecomb(p)) {
601    q = findunique(p);
602    r = q->next;
603    s = q->next->next;
604    q = q->back;
605    copycoal(q,r);
606    copycoal(q,s);
607    subrangefc(&(r->coal),s->recstart,s->recend);
608    subrangefc(&(s->coal),r->recstart,r->recend);
609 } else {
610    subtrees = NULL;
611    q = findunique(p);
612    findsubtrees_node(op,data,tfc,tr,&subtrees);
613    makecoal(op,data,tr,tfc,&(q->coal),q,subtrees);
614    free(subtrees);
615 }
616 
617 } /* fix_coal */
618 
619 
620 /******************************************************************
621  * makecoal() creates the appropiate coal array for the passed in *
622  * tymeslice.                                                     *
623  * makecoal() is nodelet specific, and the passed in nodelet must *
624  * have correct information contained in its ranges array.        *
625  * makecoal() is nodelet specific iff "p" is passed in as non-NULL*/
makecoal(option_struct * op,data_fmt * data,tree * tr,tlist * tfc,long ** coal,node * p,long * subtrees)626 void makecoal(option_struct *op, data_fmt *data, tree *tr,
627    tlist *tfc, long **coal, node *p, long *subtrees)
628 {
629 long i;
630 
631 init_coal_alloc(coal,1L);
632 (*coal)[1] = 0;
633 (*coal)[2] = countsites(op,data)-1;
634 
635 for(i = 0; i < subtrees[0]; i++) {
636    if (p)
637       if (!inrange(p->ranges,subtrees[2*i+1])) {
638          subrangefc(coal,subtrees[2*i+1],subtrees[2*i+2]);
639          continue;
640       }
641 
642    if (is_fc(tfc,subtrees[2*i+1]))
643       subrangefc(coal,subtrees[2*i+1],subtrees[2*i+2]);
644 
645 }
646 
647 } /* makecoal */
648 
649 
650 /* three functions involving updating the alias array "siteptr" */
651 
edit_alias(option_struct * op,data_fmt * data,long * sp,long cutpoint)652 void edit_alias(option_struct *op, data_fmt *data, long *sp, long cutpoint)
653 {
654   long i, alias_site, cutmarker, numsites;
655 
656   /* this looks awful because sp[i] does not actually contain
657    the alias site, it contains the alias site + 1 (to avoid zero). */
658 
659   /* cutpoint is the first site *after* the recombination */
660 
661   numsites = getdata_nummarkers(op,data);
662   cutmarker = sitetorightmarker(op,data,cutpoint);
663   if (cutmarker == FLAGLONG) return;
664 
665   for(i=cutmarker;i<numsites;i++) {
666     alias_site = sp[i]-1;
667     if(alias_site < cutmarker && alias_site+1 > 0) sp[i]*= -1;
668   }
669 } /* edit_alias */
670 
671 
traverse_rebuild_alias(option_struct * op,data_fmt * data,tlist * tstart,long * sp)672 void traverse_rebuild_alias(option_struct *op, data_fmt *data,
673   tlist *tstart, long *sp)
674 {
675 tlist *t;
676 node *p;
677 
678 for(t = tstart; t != NULL; t = t->succ) {
679    p = t->eventnode;
680    if (!isrecomb(p)) continue;
681    if (p->recstart == 0) edit_alias(op,data,sp,p->recend+1);
682    else edit_alias(op,data,sp,p->recstart);
683 }
684 
685 } /* traverse_rebuild_alias */
686 
687 
rebuild_alias(option_struct * op,data_fmt * data,long * sp)688 void rebuild_alias(option_struct *op, data_fmt *data, long *sp)
689 {
690   long i, numsites;
691 
692   numsites = getdata_nummarkers(op,data);
693 
694   for(i=0;i<numsites;i++) if (sp[i]<0) sp[i]*= -1;
695   traverse_rebuild_alias(op,data,curtree->tymelist,sp);
696 } /* rebuild_alias */
697 
698 
699 /****************************************************************
700  * contrib() sets the passed in "ranges" field, using "p".  "p" *
701  * points to the nodelet at the top of the relevant branch.     */
contrib(option_struct * op,data_fmt * data,node * p,long ** newranges)702 void contrib(option_struct *op, data_fmt *data, node *p, long **newranges)
703 {
704 node *q, *r;
705 long i, numremove;
706 
707 
708 if(istip(p)) {
709    (*newranges)[0] = 1L;
710    (*newranges)[1] = 0L;
711    (*newranges)[2] = countsites(op,data)-1;
712    (*newranges)[3] = FLAGLONG;
713    return;
714 }
715 
716 if(isrecomb(p)) {
717    q = findunique(p)->back;
718    init_ranges_alloc(newranges,q->ranges[0]);
719    memcpy((*newranges),q->ranges,(2*q->ranges[0]+2)*sizeof(long));
720 /* first remove the leading excess ranges */
721    for(i = 1, numremove = 0; (*newranges)[i] != FLAGLONG; i+=2) {
722       if(p->recstart > (*newranges)[i+1]) {numremove+=2; continue;}
723       if(p->recstart > (*newranges)[i]) (*newranges)[i] = p->recstart;
724       break;
725    }
726    memmove(&(*newranges)[1],&(*newranges)[1+numremove],
727       (2*(*newranges)[0]-numremove+1)*sizeof(long));
728    (*newranges)[0] -= numremove/2;
729 /* then removing the trailing excess ranges */
730    for(i = 2*(*newranges)[0]-1, numremove = 0; i+1 != 0; i-=2) {
731       if(p->recend < (*newranges)[i]) {numremove++; continue;}
732       if(p->recend < (*newranges)[i+1]) (*newranges)[i+1] = p->recend;
733       break;
734    }
735    (*newranges)[i+2] = FLAGLONG;
736    (*newranges)[0] -= numremove;
737 } else {
738    q = p->next->back;
739    r = p->next->next->back;
740    init_ranges_alloc(newranges,q->ranges[0]);
741    memcpy((*newranges),q->ranges,(2*q->ranges[0]+2)*sizeof(long));
742    for(i = 1; r->ranges[i] != FLAGLONG; i+=2)
743       addrange(newranges,r->ranges[i],r->ranges[i+1]);
744 }
745 
746 } /* contrib */
747 
748 
749 /***************************************************************
750  * fix_coal_ranges() updates the "ranges" of a coalescent node */
fix_coal_ranges(option_struct * op,data_fmt * data,node * p)751 void fix_coal_ranges(option_struct *op, data_fmt *data, node *p)
752 {
753   p = findunique(p);
754   contrib(op,data,p,&p->ranges);
755 } /* fix_coal_ranges */
756 
757 
758 /***************************************************************
759  * fix_rec_ranges() updates the "ranges" of a recombinant node */
fix_rec_ranges(option_struct * op,data_fmt * data,node * p)760 void fix_rec_ranges(option_struct *op, data_fmt *data, node *p)
761 {
762   p = findunique(p);
763   contrib(op,data,p->next,&p->next->ranges);
764   contrib(op,data,p->next->next,&p->next->next->ranges);
765 } /* fix_rec_ranges */
766 
767 
popbranch(tlist * t,long branch)768 boolean popbranch(tlist *t, long branch)
769 {
770   long i;
771   boolean found;
772 
773   found = FALSE;
774   for(i=0;i<t->numbranch;i++) {
775     if (t->branchlist[i]!=NULL) {
776       if (t->branchlist[i]->number==branch) {
777         t->branchlist[i]=NULL;
778         found = TRUE;
779       }
780     }
781   }
782   return(found);
783 } /* popbranch */
784 
785 
subbranch(tlist * t,long oldbranch,node * newbranch)786 boolean subbranch(tlist *t, long oldbranch, node *newbranch)
787 {
788   long i;
789   boolean found;
790 
791   found = FALSE;
792   for(i=0;i<t->numbranch;i++) {
793     if (t->branchlist[i]!=NULL) {
794       if (t->branchlist[i]->number==oldbranch) {
795         t->branchlist[i]=newbranch;
796         found = TRUE;
797       }
798     }
799   }
800   return(found);
801 } /* subbranch */
802 
803 
poptymelist(node * p)804 void poptymelist (node *p)
805 {  /* remove futile tymelist entry */
806    boolean done;
807    node *q;
808    tlist *s, *t, *u;
809 
810    t = gettymenode(curtree, p->number);
811    u = t;
812    if(isrecomb(p)) {
813      s = u->succ;
814      do {
815        if(s==NULL) break;
816        done = !popbranch(s,p->number);
817        s = s->succ;
818      } while (!done);
819      u->prev->age=t->age;
820      u->prev->succ=u->succ;
821      if (t->succ != NULL) u->succ->prev=u->prev;
822      freetymenode(u);
823    } else {
824      s = u->succ;
825      if(p->next->top) q=p->next->next->back;
826      else q=p->next->back;
827      do {
828        if(s==NULL) break;
829        done = !subbranch(s,p->number,q);
830        s = s->succ;
831      } while (!done);
832      u->prev->age=t->age;
833      u->prev->succ=u->succ;
834      if (u->succ != NULL) u->succ->prev=u->prev;
835      freetymenode(u);
836    }
837 } /* poptymelist */
838 
839 
fixbranch(tlist * t)840 void fixbranch(tlist *t)
841 {
842   long i, j, nullcnt, newnum;
843   node **newarray;
844 
845   nullcnt = 0;
846   for(i=0;i<t->numbranch;i++) {
847     if(t->branchlist[i]==NULL) nullcnt++;
848   }
849   if(nullcnt==0) return;
850   /* workaround to avoid callocing 0 (or less) elements */
851   newnum = (t->numbranch-nullcnt < 1) ? 1 : t->numbranch-nullcnt;
852   newarray = (node **)calloc(1,newnum*sizeof(node *));
853   j = 0;
854   for(i=0;i<t->numbranch;i++) {
855     if(t->branchlist[i]!=NULL) {
856       newarray[j]=t->branchlist[i];
857       j++;
858     }
859   }
860   free(t->branchlist);
861   t->numbranch = newnum;
862   t->branchlist=newarray;
863 } /* fixbranch */
864 
865 
866 /***********************************************************
867  * is_futile() checks to see if a node has been tagged for *
868  * futile removal.                                         */
is_futile(node * p)869 boolean is_futile(node *p)
870 {
871 
872 return((p->futileflag == FLAGLONG));
873 
874 } /* is_futile */
875 
876 
877 /**********************************************************
878  * find_nonfutile() finds the first non-futile node along *
879  * the path of nodes going in the direction indicated by  *
880  * upwards (TRUE = up, FALSE = down).                     */
find_nonfutile(node * p,node * cutnode,boolean upwards)881 node *find_nonfutile(node *p, node *cutnode, boolean upwards)
882 {
883 node *q;
884 
885 if (p == cutnode) return(NULL);
886 if (istip(p) || !is_futile(p)) return(p);
887 
888 p = findunique(p);
889 if (isrecomb(p)) {
890    if (upwards) q = find_nonfutile(p->back,cutnode,upwards);
891    else {
892       q = find_nonfutile(p->next->back,cutnode,upwards);
893       if (!q) q = find_nonfutile(p->next->next->back,cutnode,upwards);
894    }
895 } else {
896    if (upwards) {
897       q = find_nonfutile(p->next->back,cutnode,upwards);
898       if (!q) q = find_nonfutile(p->next->next->back,cutnode,upwards);
899    } else q = find_nonfutile(p->back,cutnode,upwards);
900 }
901 
902 return(q);
903 
904 } /* find_nonfutile */
905 
906 
907 /**********************************************************
908  * tag_futile() sets a flag to indicate that it should be *
909  * removed.  The flag set is for recstart & recend set to *
910  * FLAGLONG;                                              */
tag_futile(node * p)911 void tag_futile(node *p)
912 {
913 
914 if (isrecomb(p)) {
915    p->futileflag = p->next->futileflag = FLAGLONG;
916    p->next->next->futileflag = FLAGLONG;
917    tag_futile(p->next->back);
918    if (p->next->next->back != curtree->root)
919       tag_futile(p->next->next->back);
920    return;
921 } else {
922    if (!is_futile(p)) {
923       p->futileflag = p->next->futileflag = FLAGLONG;
924       p->next->next->futileflag = FLAGLONG;
925       return;
926    } else {
927       if (p->next->top) tag_futile(p->next->back);
928       else tag_futile(p->next->next->back);
929    }
930 }
931 
932 } /* tag_futile */
933 
934 
935 /**********************************************************************
936  * renamebrlist() goes through a brlist replacing old branchtops with *
937  * the new branchtop.                                                 */
renamebrlist(brlist ** bigbr,brlist * start,node * oldtop,node * newtop)938 void renamebrlist(brlist **bigbr, brlist *start, node *oldtop, node *newtop)
939 {
940 brlist *br, *brsucc;
941 
942 for(br = start; br != NULL; br = brsucc) {
943    brsucc = br->succ;
944    if (br->branchtop == oldtop) {
945       br->branchtop = newtop;
946       if (newtop->tyme >= br->endtyme) {
947          br_remove(bigbr,br);
948          continue;
949       }
950       if (br->starttyme < newtop->tyme) {
951          br->starttyme = newtop->tyme;
952          if (br->prev) br->prev->succ = br->succ;
953          else (*bigbr) = br->succ;
954          if (br->succ) br->succ->prev = br->prev;
955          hookup_brlist(bigbr,br);
956       }
957    }
958 }
959 
960 } /* renamebrlist */
961 
962 
963 /**********************************************************************
964  * drop_renamebrlist() is a coalesce specific driver for renamebrlist */
drop_renamebrlist(brlist ** bigbr,node * oldtop,node * newtop)965 void drop_renamebrlist(brlist **bigbr, node *oldtop, node *newtop)
966 {
967 brlist *br;
968 
969 if (!bigbr) return;
970 
971 br = (*bigbr);
972 
973 renamebrlist(bigbr,br,oldtop,newtop);
974 
975 } /* drop_renamebrlist */
976 
977 
978 /********************************************************************
979  * drop_brfix() updates the ranges & coal information, and changes  *
980  * brlist info, for all branches which start at or after the passed *
981  * in tymelist's eventnode.                                         */
drop_brfix(option_struct * op,data_fmt * data,tree * newtree,tlist * start,brlist ** oldbr)982 void drop_brfix(option_struct *op, data_fmt *data, tree *newtree,
983    tlist *start, brlist **oldbr)
984 {
985 node *p, *q, *r;
986 tlist *t;
987 long *oldcoal1, *oldcoal2;
988 dnadata *dna;
989 
990 oldcoal1 = oldcoal2 = NULL;
991 dna = data->dnaptr;
992 
993 for (t = start; t != NULL; t = t->succ) {
994    p = findunique(t->eventnode);
995    if (istip(p)) continue;
996    if (isrecomb(p)) {
997       q = p->next;
998       r = p->next->next;
999       if (op->fc) {
1000          fix_rec_ranges(op,data,p);
1001          init_coal_alloc(&oldcoal1,q->coal[0]);
1002          init_coal_alloc(&oldcoal2,r->coal[0]);
1003          memcpy(oldcoal1,q->coal,(2*q->coal[0]+2)*sizeof(long));
1004          memcpy(oldcoal2,r->coal,(2*r->coal[0]+2)*sizeof(long));
1005          fix_coal(op,data,newtree,t,p);
1006          if (!sameranges(oldcoal1,q->coal))
1007             addbrlist(op,data,oldbr,q,oldcoal1,q->coal,NULL,q->tyme,
1008                q->back->tyme,FALSE);
1009          if (!sameranges(oldcoal2,r->coal))
1010             addbrlist(op,data,oldbr,r,oldcoal2,r->coal,NULL,r->tyme,
1011                r->back->tyme,FALSE);
1012       } else {
1013          init_ranges_alloc(&oldcoal1,q->ranges[0]);
1014          init_ranges_alloc(&oldcoal2,r->ranges[0]);
1015          memcpy(oldcoal1,q->ranges,(2*q->ranges[0]+2)*sizeof(long));
1016          memcpy(oldcoal2,r->ranges,(2*r->ranges[0]+2)*sizeof(long));
1017          fix_rec_ranges(op,data,p);
1018          if (!sameranges(oldcoal1,q->ranges))
1019             addbrlist(op,data,oldbr,q,oldcoal1,q->ranges,NULL,q->tyme,
1020                q->back->tyme,FALSE);
1021          if (!sameranges(oldcoal2,r->ranges))
1022             addbrlist(op,data,oldbr,r,oldcoal2,r->ranges,NULL,r->tyme,
1023                r->back->tyme,FALSE);
1024       }
1025    } else {
1026       if (op->fc) {
1027          fix_coal_ranges(op,data,p);
1028          init_coal_alloc(&oldcoal1,p->coal[0]);
1029          memcpy(oldcoal1,p->coal,(2*p->coal[0]+2)*sizeof(long));
1030          fix_coal(op,data,newtree,t,p);
1031          if (!sameranges(oldcoal1,p->coal))
1032             addbrlist(op,data,oldbr,p,oldcoal1,p->coal,NULL,
1033                p->tyme,p->back->tyme,FALSE);
1034       } else {
1035          init_ranges_alloc(&oldcoal1,p->ranges[0]);
1036          memcpy(oldcoal1,p->ranges,(2*p->ranges[0]+2)*sizeof(long));
1037          fix_coal_ranges(op,data,p);
1038          if (!sameranges(oldcoal1,p->ranges))
1039             addbrlist(op,data,oldbr,p,oldcoal1,p->ranges,NULL,
1040                p->tyme,p->back->tyme,FALSE);
1041       }
1042    }
1043 }
1044 
1045 if (oldcoal1) free(oldcoal1);
1046 if (oldcoal2) free(oldcoal2);
1047 
1048 } /* drop_brfix */
1049 
1050 
1051 /************************************************************
1052  * samesites() checks to see if the segranges array and the *
1053  * ranges array could be describing the same set of sites.  */
samesites(int * segranges,long * ranges,long numsites)1054 boolean samesites(int *segranges, long *ranges, long numsites)
1055 {
1056 long i;
1057 
1058 for(i = 0; i < numsites; i++) {
1059    if(segranges[i] == 1 || segranges[i] == 2) {
1060       if(!inrange(ranges,i)) return(FALSE);
1061    } else {
1062       if(inrange(ranges,i)) return(FALSE);
1063    }
1064 }
1065 
1066 return(TRUE);
1067 
1068 } /* samesites */
1069 
1070 
1071 /****************************************************************
1072  * treelegalbrlist() checks to make sure that a brlist entry is *
1073  * legal given the tree.                                        */
treelegalbrlist(option_struct * op,data_fmt * data,tree * tr,brlist ** bigbr,brlist * target)1074 void treelegalbrlist(option_struct *op, data_fmt *data, tree *tr,
1075    brlist **bigbr, brlist *target)
1076 {
1077 long *comp;
1078 node *top, *bottom, *treenode;
1079 
1080 top = target->branchtop;
1081 bottom = top->back;
1082 treenode = tr->nodep[top->number];
1083 
1084 if (isrecomb(top)) {
1085    if(treenode != top && treenode != otherparent(top)) {
1086       br_remove(bigbr,target);
1087       return;
1088    }
1089 } else {
1090    if(treenode != top) {
1091       br_remove(bigbr,target);
1092       return;
1093    }
1094 }
1095 
1096 if (target->endtyme > bottom->tyme) {
1097    if (isrecomb(bottom)) {
1098       bottom = findunique(bottom);
1099       if (!bottom->next->back) top = bottom->next->next;
1100       else if (!bottom->next->next->back) top = bottom->next;
1101       else {
1102          comp = ((op->fc) ? bottom->next->coal : bottom->next->ranges);
1103          top =
1104          (samesites(target->segranges,comp,countsites(op,data))
1105          ? bottom->next : bottom->next->next);
1106       }
1107    } else top = findunique(bottom);
1108 
1109    if (target->endtyme < curtree->root->back->tyme)
1110       addbrlist(op,data,bigbr,top,NULL,NULL,target->segranges,bottom->tyme,
1111          target->endtyme,FALSE);
1112    target->endtyme = bottom->tyme;
1113 }
1114 
1115 } /* treelegalbrlist */
1116 
1117 
1118 /******************************************************************
1119  * samebranch() checks to see if the two segments are on the same *
1120  * branch (i.e. whether they have the same tops).                 */
samebranch(brlist * br1,brlist * br2)1121 boolean samebranch(brlist *br1, brlist *br2)
1122 {
1123 
1124 return(br1->branchtop == br2->branchtop);
1125 
1126 } /* samebranch */
1127 
1128 
1129 /********************************************************************
1130  * checktreebranch() checks to see if a segment is properly part of *
1131  * the branch whose top is p.                                       *
1132  *                                                                  *
1133  * It returns: 0 if no match is found                               *
1134  *             1 if starts match                                    *
1135  *            -1 if ends match                                      *
1136  *             2 if both start and end match                        */
checktreebranch(brlist * br,node * p,double starttyme,double endtyme)1137 long checktreebranch(brlist *br, node *p, double starttyme,
1138    double endtyme)
1139 {
1140 
1141 if (br->branchtop != p) return(0L);
1142 
1143 if (br->starttyme == starttyme && br->endtyme == endtyme) return(2L);
1144 if (br->starttyme == starttyme) return(1L);
1145 if (br->endtyme == endtyme) return(-1L);
1146 
1147 return(0L);
1148 
1149 } /* checktreebranch */
1150 
1151 
1152 /********************************************************************
1153  * sametreebranch() checks to see if a segment was ever on the same *
1154  * branch as the branch possibly bisected by the node p.            *
1155  *                                                                  *
1156  * It returns: 0 if no match is found                               *
1157  *             1 if starts match                                    *
1158  *            -1 if ends match                                      *
1159  *             2 if both start and end match                        */
sametreebranch(brlist * br,node * p,double starttyme,double endtyme)1160 long sametreebranch(brlist *br, node *p, double starttyme,
1161    double endtyme)
1162 {
1163 node *target;
1164 long match;
1165 
1166 match = checktreebranch(br,p,starttyme,endtyme);
1167 
1168 if (match /*|| istip(p)*/) return(match);
1169 
1170 target = findunique(p);
1171 if (isrecomb(target)) {
1172    match = checktreebranch(br,target->back,starttyme,endtyme);
1173 } else {
1174    match = checktreebranch(br,target->next->back,starttyme,endtyme);
1175    if (match) return(match);
1176    match = checktreebranch(br,target->next->next->back,starttyme,endtyme);
1177 }
1178 
1179 return(match);
1180 
1181 } /* sametreebranch */
1182 
1183 
1184 /****************************************************************
1185  * isoverlap() checks to see if two brlist entries overlap each *
1186  * other on the tree.                                           */
isoverlap(brlist * br1,brlist * br2)1187 boolean isoverlap(brlist *br1, brlist *br2)
1188 {
1189 double br1start, br2start;
1190 
1191 if (!samebranch(br1,br2)) return(FALSE);
1192 
1193 br1start = br1->starttyme;
1194 br2start = br2->starttyme;
1195 
1196 if (((br1start > br2start) && (br1start < br2->endtyme)) ||
1197     ((br2start > br1start) && (br2start < br1->endtyme))) return(TRUE);
1198 
1199 return(FALSE);
1200 
1201 
1202 } /* isoverlap */
1203 
1204 
1205 /******************************************************************
1206  * iscontainedin() checks to see if one brlist entry is entirely  *
1207  * within another.                                                */
iscontainedin(brlist * br1,brlist * br2)1208 boolean iscontainedin(brlist *br1, brlist *br2)
1209 {
1210 
1211 if (!samebranch(br1,br2)) return(FALSE);
1212 
1213 if(((br1->starttyme > br2->starttyme) && (br1->endtyme < br2->endtyme))
1214   || ((br2->starttyme > br1->starttyme) && (br2->endtyme < br1->endtyme)))
1215   return(TRUE);
1216 
1217 return(FALSE);
1218 
1219 } /* iscontainedin */
1220 
1221 
1222 /****************************************************************
1223  * mash_brlist() searches a brlist for a match to its "target". *
1224  * If it finds one, it mashes the two entries together.         */
mash_brlist(tree * tr,brlist * start,brlist * target)1225 void mash_brlist(tree *tr, brlist *start, brlist *target)
1226 {
1227 brlist *br, *brupper, *brlower;
1228 double temp;
1229 
1230 for(br = start; br != NULL; br = br->succ) {
1231    if(!isoverlap(target,br) && !iscontainedin(target,br)) continue;
1232    if(target->starttyme < br->starttyme) {
1233       brupper = target;
1234       brlower = br;
1235    } else {
1236       brupper = br;
1237       brlower = target;
1238    }
1239    if (iscontainedin(target,br)) {
1240       brupper->endtyme = brlower->starttyme;
1241       continue;
1242    }
1243    temp = brupper->endtyme;
1244    brupper->endtyme = brlower->starttyme;
1245    brlower->starttyme = temp;
1246 }
1247 
1248 } /* mash_brlist */
1249 
1250 
1251 /*****************************************************************
1252  * consolidate_brlist() attempts to remove and replace redundate *
1253  * entries from a brlist.  The tree must be correct.             */
consolidate_brlist(option_struct * op,data_fmt * data,tree * tr,brlist ** bigbr)1254 void consolidate_brlist(option_struct *op, data_fmt *data, tree *tr,
1255    brlist **bigbr)
1256 {
1257 brlist *br, *brsucc;
1258 
1259 if (!bigbr) return;
1260 
1261 for(br = (*bigbr); br != NULL; br = brsucc) {
1262    brsucc = br->succ;
1263    treelegalbrlist(op,data,tr,bigbr,br);
1264 }
1265 
1266 for(br = (*bigbr); br != NULL; br = br->succ) {
1267    mash_brlist(tr,br->succ,br);
1268 }
1269 
1270 } /* consolidate_brlist */
1271 
1272 
1273 /******************************************************************
1274  * br_remove() performs a very basic removal of the passed brlist *
1275  * element from whatever brlist it is attached to, then frees it. */
br_remove(brlist ** bigbr,brlist * target)1276 void br_remove(brlist **bigbr, brlist *target)
1277 {
1278 
1279 if (target->prev) target->prev->succ = target->succ;
1280 else (*bigbr) = target->succ;
1281 if (target->succ) target->succ->prev = target->prev;
1282 
1283 freebrlist(target);
1284 
1285 } /* br_remove */
1286 
1287 
1288 /*************************************
1289  * printbrlist() prints out a brlist */
printbrlist(brlist * start)1290 void printbrlist(brlist *start)
1291 {
1292 brlist *br;
1293 
1294 fprintf(ERRFILE,"Brlist follows\n");
1295 for(br = start; br != NULL; br = br->succ) {
1296    fprintf(ERRFILE,"   top %3ld at tyme %12.8f [%12.8f/%12.8f]",
1297       br->branchtop->number,br->branchtop->tyme,br->starttyme, br->endtyme);
1298    fprintf(ERRFILE," with newlinks %f\n",br->numnewactives);
1299 }
1300 
1301 } /* printbrlist */
1302 
1303 
1304 /*********************************************************************
1305  * find_futilecoaldtr() returns the "traversed" daughter node from a *
1306  * the passed node "p".                                              */
find_futilecoaldtr(node * cutnode,node * p)1307 node *find_futilecoaldtr(node *cutnode, node *p)
1308 {
1309 node *q;
1310 
1311 q = findtop(p);
1312 
1313 if (is_futile(q->next->back) || q->next->back == cutnode)
1314    return(q->next->next->back);
1315 else return(q->next->back);
1316 
1317 } /* find_futilecoaldtr */
1318 
1319 
1320 /********************************************************************
1321  * remove_futile() removes the nodes from the tree that have been   *
1322  * tagged by tag_futile, while maintaing brlist entries for them.   *
1323  * remove_futile() assumes that the first entry in the tymelist     *
1324  * contains the tips and so will never be removed.  It also assumes *
1325  * that coalescent nodes require tree clean-up, whereas recombinant *
1326  * nodes may be simply removed.                                     *
1327  * Traverse the tymelist in reverse order so that path of removal   *
1328  * info is preserved.                                               */
remove_futile(option_struct * op,data_fmt * data,tree * newtree,tree * oldtree,node * cutnode,boolean * nodenumber,brlist ** br)1329 void remove_futile(option_struct *op, data_fmt *data, tree *newtree,
1330    tree *oldtree, node *cutnode, boolean *nodenumber, brlist **br)
1331 {
1332 long i, numnodes, **oranges, *oldranges, topcount, *actives;
1333 double btyme;
1334 tlist *t, *tsucc, *firstfutile;
1335 node *p, *q, *dtr, *par, **obnode, **otnode, *oldnode, *newtopnode,
1336   **tops;
1337 dnadata *dna;
1338 
1339 dna = data->dnaptr;
1340 
1341 numnodes = 2 * oldtree->numcoals + 2;
1342 obnode = (node **)calloc(numnodes,sizeof(node *));
1343 otnode = (node **)calloc(numnodes,sizeof(node *));
1344 tops = (node **)calloc(numnodes,sizeof(node *));
1345 oranges = (long **)calloc(numnodes,sizeof(long *));
1346 
1347 topcount = 0;
1348 firstfutile = NULL;
1349 
1350 /* scanning tymelist from the bottom up */
1351 for(t = newtree->tymelist; t->succ != NULL; t = t->succ) ;
1352 
1353 /* modify the basic underlying tree structure */
1354 for(; t->prev != NULL; t = t->prev) {
1355    obnode[t->eventnode->number] = otnode[t->eventnode->number] = NULL;
1356    if (!is_futile(t->eventnode)) continue;
1357    firstfutile = t;
1358    p = t->eventnode;
1359    nodenumber[p->number] = FALSE;
1360    if (isrecomb(p)) {
1361       newtree->numrecombs--;
1362       q = findunique(p);
1363       otnode[p->number] = (is_futile(q->next->back)) ?
1364                              q->next : q->next->next;
1365    } else {
1366       obnode[p->number] = p->back;
1367       dtr = find_nonfutile(p,cutnode,TRUE);
1368       otnode[p->number] = dtr;
1369       if (dtr != NULL) {
1370         tops[topcount] = dtr;
1371         topcount++;
1372       }
1373       actives = (op->fc) ? p->coal : p->ranges;
1374       init_coal_alloc(&oranges[p->number],actives[0]);
1375       memcpy(oranges[p->number],actives,(2*actives[0]+2)*sizeof(long));
1376       if (!is_futile(p->back)) {
1377          par = p->back;
1378          hookup(dtr,par);
1379          fixlength(op,data,dtr);
1380       }
1381       newtree->numcoals--;
1382    }
1383 }
1384 
1385 /* remove futile branches from the branchlists */
1386 for(t = firstfutile; t != NULL; t = tsucc) {
1387    tsucc = t->succ;
1388    if (!is_futile(t->eventnode)) continue;
1389    p = t->eventnode;
1390    if (isrecomb(p)) {
1391       if (p == cutnode || otherparent(p) == cutnode) {
1392          if (p == cutnode) {
1393             remove_branch(t,p);
1394             rename_branch(t,findunique(p)->back,otherparent(p));
1395          } else {
1396             remove_branch(t,otherparent(p));
1397             rename_branch(t,findunique(p)->back,p);
1398          }
1399       } else {
1400          remove_branch(t,p);
1401          remove_branch(t,otherparent(p));
1402       }
1403    } else {
1404       if (otnode[p->number]) rename_branch(t,otnode[p->number],p);
1405       else remove_branch(t,p);
1406    }
1407 }
1408 
1409 extbranch(curtree,gettymenode(newtree,cutnode->number),cutnode);
1410 
1411 /* scanning tymelist from the top down, updating coal and ranges arrays */
1412 for (t = firstfutile; t != NULL; t = t->succ) {
1413    p = findunique(t->eventnode);
1414    if (!is_futile(p)) {
1415       if (isrecomb(p)) {
1416          fix_rec_ranges(op,data,p);
1417       } else {
1418          fix_coal_ranges(op,data,p);
1419       }
1420       if (op->fc) fix_coal(op,data,newtree,t,p);
1421    }
1422 }
1423 
1424 
1425 /* scanning tymelist from the top down again, building the brlist,
1426    and finally removing the remnant tymelist entries */
1427 for (t = firstfutile; t != NULL; t = tsucc) {
1428    p = findunique(t->eventnode);
1429    tsucc = t->succ;
1430    if (!is_futile(p)) {
1431       oldnode = findunique(oldtree->nodep[p->number]);
1432       if (isrecomb(p)) {
1433          if (op->fc) {
1434             oldranges = oldnode->next->coal;
1435             newtopnode = p->next;
1436             btyme = oldnode->next->back->tyme;
1437             addbrlist(op,data,br,newtopnode,oldranges,newtopnode->coal,
1438                NULL,newtopnode->tyme,btyme,TRUE);
1439 
1440             oldranges = oldnode->next->next->coal;
1441             newtopnode = p->next->next;
1442             btyme = oldnode->next->next->back->tyme;
1443             addbrlist(op,data,br,newtopnode,oldranges,newtopnode->coal,
1444                NULL,newtopnode->tyme,btyme,TRUE);
1445          } else {
1446             oldranges = oldnode->next->ranges;
1447             newtopnode = p->next;
1448             btyme = oldnode->next->back->tyme;
1449             addbrlist(op,data,br,newtopnode,oldranges,newtopnode->ranges,
1450                NULL,newtopnode->tyme,btyme,TRUE);
1451 
1452             oldranges = oldnode->next->next->ranges;
1453                newtopnode = p->next->next;
1454             btyme = oldnode->next->next->back->tyme;
1455             addbrlist(op,data,br,newtopnode,oldranges,newtopnode->ranges,
1456                NULL,newtopnode->tyme,btyme,TRUE);
1457          }
1458 
1459       } else {
1460          if (op->fc) {
1461             oldranges = oldnode->coal;
1462             newtopnode = p;
1463             btyme = oldnode->back->tyme;
1464             addbrlist(op,data,br,newtopnode,oldranges,newtopnode->coal,
1465                NULL,newtopnode->tyme,btyme,TRUE);
1466          } else {
1467             oldranges = oldnode->ranges;
1468             newtopnode = p;
1469             btyme = oldnode->back->tyme;
1470             addbrlist(op,data,br,newtopnode,oldranges,newtopnode->ranges,
1471                NULL,newtopnode->tyme,btyme,TRUE);
1472          }
1473       }
1474    } else {
1475       if (!isrecomb(p)) {
1476          if (op->fc) {
1477             addbrlist(op,data,br,otnode[p->number],oranges[p->number],
1478                obnode[p->number]->back->coal,NULL,p->tyme,
1479                obnode[p->number]->tyme,TRUE);
1480          } else {
1481             addbrlist(op,data,br,otnode[p->number],oranges[p->number],
1482                obnode[p->number]->back->ranges,NULL,p->tyme,
1483                obnode[p->number]->tyme,TRUE);
1484          }
1485       }
1486       if (isrecomb(p)) subtymelist(t,p->next,TRUE);
1487       else subtymelist(t,p,TRUE);
1488       freenode(p);
1489    }
1490 }
1491 
1492 /* The following loop deals with the case (and probably others as well)
1493    where the cutnode is the top of a recombinant loop and the non-cut
1494    branch needs to be extended down to replace the bottom nodes' branch
1495 */
1496 for(i=0; i<topcount; i++) {
1497     t = gettymenode(newtree,tops[i]->number);
1498     readdbranch(newtree,t,tops[i]);
1499   }
1500 
1501 cutnode->back = NULL;
1502 
1503 free(obnode);
1504 free(otnode);
1505 free(tops);
1506 for(i = 0; i < numnodes; i++) if (oranges[i]) free(oranges[i]);
1507 free(oranges);
1508 
1509 } /* remove_futile */
1510 
1511 
1512 /**************************************************************
1513 *  Re-introduces a branch into the tymelist after it has      *
1514 *  been stripped out during remove_futile.  This code is      *
1515 *  quite specific to remove_futile; don't use it generically. */
readdbranch(tree * newtree,tlist * u,node * addbranch)1516 void readdbranch(tree *newtree, tlist *u, node *addbranch)
1517 {
1518   long i;
1519   tlist *t;
1520   boolean found;
1521 
1522   for (t = u; t!=NULL; t=t->succ) {
1523     if(t->eventnode->number==addbranch->back->number) return;
1524     found = FALSE;
1525     for (i = 0; i < t->numbranch; i++) {
1526       if (t->branchlist[i]==addbranch) found = TRUE;
1527     }
1528     if (!found) {
1529       t->numbranch++;
1530       t->branchlist = (node **)realloc(t->branchlist,
1531         t->numbranch*sizeof(node *));
1532       t->branchlist[t->numbranch - 1] = addbranch;
1533     }
1534   }
1535 } /* addbranch */
1536 
1537 
1538 /***********************************************************************
1539  * rembranch() removes the passed branch from all tymelist branchlists *
1540  * from "start" to the bottom/end of the tree.                         */
rembranch(tree * newtree,tlist * start,node * sbranch)1541 void rembranch(tree *newtree, tlist *start, node *sbranch)
1542 {
1543 long i;
1544 tlist *t;
1545 boolean found;
1546 node **newlist;
1547 
1548 for (t = start; t!=NULL; t=t->succ) {
1549     newlist = (node **)calloc(t->numbranch,sizeof(node *));
1550     found = FALSE;
1551     for(i = 0; i < t->numbranch; i++) {
1552        if (!found) newlist[i] = t->branchlist[i];
1553        else newlist[i-1] = t->branchlist[i];
1554        if (t->branchlist[i] == sbranch) found = TRUE;
1555     }
1556     free(t->branchlist);
1557     t->branchlist = newlist;
1558     if (found) t->numbranch--;
1559 }
1560 
1561 } /* rembranch */
1562 
1563 
1564 
1565 /******************************************************************
1566  * extbranch() adds the passed branch to all tymelist branchlists *
1567  * from "start" to the bottom/end of the tree.                    */
extbranch(tree * newtree,tlist * start,node * addbranch)1568 void extbranch(tree *newtree, tlist *start, node *addbranch)
1569 {
1570   long i;
1571   tlist *t;
1572   boolean found;
1573 
1574   for (t = start; t!=NULL; t=t->succ) {
1575     found = FALSE;
1576     for (i = 0; i < t->numbranch; i++) {
1577       if (t->branchlist[i]==addbranch) found = TRUE;
1578     }
1579     if (!found) {
1580       t->numbranch++;
1581       t->branchlist = (node **)realloc(t->branchlist,
1582         t->numbranch*sizeof(node *));
1583       t->branchlist[t->numbranch - 1] = addbranch;
1584     }
1585   }
1586 
1587 } /* extbranch */
1588 
1589 
isactive(node * p,linlist * u)1590 boolean isactive(node *p, linlist *u)
1591 {
1592 linlist *t;
1593 
1594 for(t = u; t != NULL; t = t->succ)
1595    if (p == t->branchtop) return(TRUE);
1596 
1597 return(FALSE);
1598 
1599 } /* isactive */
1600 
1601 
countinactive(option_struct * op,tlist * t,linlist * u)1602 long countinactive(option_struct *op, tlist *t, linlist *u)
1603 {
1604 long i, numinactive, *actives;
1605 
1606 numinactive = t->numbranch;
1607 for (i = 0; i < t->numbranch; i++) {
1608    if (isactive(t->branchlist[i],u)) {numinactive--; continue;}
1609    actives = (op->fc) ? t->branchlist[i]->coal :
1610                         t->branchlist[i]->ranges;
1611    if (!actives[0]) {numinactive--; continue;}
1612 }
1613 
1614 return(numinactive);
1615 
1616 } /* countinactive */
1617 
1618 
1619 /*********************************************************************
1620  * pickbrtarget() returns a randum brlist segment from the passed in *
1621  * brlist using the passed in number of active sites as a guide.     */
pickbrtarget(brlist * start,double numactive)1622 brlist *pickbrtarget(brlist *start, double numactive)
1623 {
1624 double pick;
1625 brlist *br;
1626 
1627 pick = randum() * numactive - start->numnewactives;
1628 for(br = start; pick > 0; br = br->succ) pick -= br->succ->numnewactives;
1629 
1630 return(br);
1631 
1632 } /* pickbrtarget */
1633 
1634 
1635 /*********************************************************************
1636  * pickbrcross() picks a randum point of crossover within the passed *
1637  * in brsegment.                                                     */
pickbrcross(option_struct * op,data_fmt * data,brlist * source)1638 long pickbrcross(option_struct *op, data_fmt *data, brlist *source)
1639 {
1640 long cross;
1641 double numactive;
1642 boolean found;
1643 
1644 numactive = randum() * source->numnewactives;
1645 found = FALSE;
1646 
1647 if (source->nfsite < source->ofsite && source->nlsite > source->olsite) {
1648    for(cross = source->nfsite; cross < source->ofsite && !found; cross++) {
1649       if (op->datatype == 'n') numactive--;
1650       else numactive -= getdata_space(op,data,cross);
1651       if (numactive < 0) {found = TRUE; break;}
1652    }
1653    if (!found)
1654       for(cross = source->olsite; cross < source->nlsite && !found; cross++) {
1655          if (op->datatype == 'n') numactive--;
1656          else numactive -= getdata_space(op,data,cross);
1657          if (numactive < 0) {found = TRUE; break;}
1658       }
1659 } else {
1660    if (source->nlsite > source->olsite && source->nfsite < source->olsite)
1661       for(cross = source->olsite; cross < source->nlsite && !found; cross++) {
1662          if (op->datatype == 'n') numactive--;
1663          else numactive -= getdata_space(op,data,cross);
1664          if (numactive < 0) {found = TRUE; break;}
1665       }
1666    else
1667       for(cross = source->nfsite; cross < source->nlsite && !found; cross++) {
1668          if (op->datatype == 'n') numactive--;
1669          else numactive -= getdata_space(op,data,cross);
1670          if (numactive < 0) {found = TRUE; break;}
1671       }
1672 }
1673 
1674 return(cross);
1675 
1676 
1677 } /* pickbrcross */
1678 
1679 
1680 /*********************************************************************
1681  * eventprobbr() is an auxiliary function to eventprob that helps it *
1682  * deal with brlist segments.                                        *
1683  *                                                                   *
1684  * Due to brsegment endpoint problems, (what endpoints to include?), *
1685  * eventprobbr() now also picks both the brlist segment that will    *
1686  * have an event, if one is desired; and what the crossover point    *
1687  * will be.  Segment and point info are passed in the bseg struct.   */
eventprobbr(option_struct * op,data_fmt * data,brlist ** bigbr,tlist * tint,double pc,double pr,double * pb,bseg * brs)1688 double eventprobbr(option_struct *op, data_fmt *data, brlist **bigbr,
1689    tlist *tint, double pc, double pr, double *pb, bseg *brs)
1690 {
1691 double ttyme, btyme, tyme, offset, brlength, stoptyme, bsitesum;
1692 brlist *br, *brsucc, *finish;
1693 
1694 bsitesum = 0.0;
1695 offset = 0.0;
1696 stoptyme = tint->age;
1697 tyme = BOGUSTREETYME;
1698 brlength = BOGUSTREETYME - 1.0;
1699 btyme = tint->eventnode->tyme;
1700 finish = NULL;
1701 
1702 while (tyme > brlength) {
1703    if (!(*bigbr)) {
1704       ttyme = btyme;
1705       btyme = stoptyme;
1706       (*pb) = 0.0;
1707    } else {
1708       if ((*bigbr)->starttyme > btyme) {
1709          ttyme = btyme;
1710          btyme = (((*bigbr)->starttyme < stoptyme) ?
1711                     (*bigbr)->starttyme : stoptyme);
1712          (*pb) = 0.0;
1713          finish = (*bigbr);
1714       } else {
1715          ttyme = (*bigbr)->starttyme;
1716          btyme = DBL_MAX;
1717          bsitesum = 0;
1718          for(br = (*bigbr); br->starttyme == ttyme; br = br->succ) {
1719             if (br->endtyme < btyme) btyme = br->endtyme;
1720             bsitesum += br->numnewactives;
1721             if (br->succ == NULL) {br = NULL; break;}
1722          }
1723          if (btyme > stoptyme) btyme = stoptyme;
1724 /* now also find anything that starts before the shortest entry ends;
1725    finish will end up pointing to the first entry we don't want to do
1726    anything with.  Assumption of contingous brlist entries contingent
1727    upon the list being sorted by starttymes, least to greatest! */
1728          finish = br;
1729          if (br) if (br->starttyme < btyme) btyme = br->starttyme;
1730          *pb = bsitesum*rec0;
1731       }
1732    }
1733 
1734    if (*pb) {
1735       brs->target = pickbrtarget((*bigbr),bsitesum);
1736       brs->cross = pickbrcross(op,data,brs->target);
1737    }
1738 
1739    /* when? */
1740    if (pc || pr || *pb) tyme = -log(randum())/(pc + pr + (*pb));
1741    else tyme = btyme + 0.1;
1742 
1743    brlength = btyme - ttyme;
1744    if (tyme > brlength) {
1745       if (*bigbr)
1746          for(br = (*bigbr); br != finish; br = brsucc) {
1747             brsucc = br->succ;
1748             br->starttyme = btyme;
1749             if (br->starttyme == br->endtyme) br_remove(bigbr,br);
1750          }
1751       offset += btyme - ttyme;
1752    }
1753 
1754    if (btyme == stoptyme) break;
1755 
1756 }
1757 
1758 return(tyme + offset);
1759 
1760 } /* eventprobbr */
1761 
1762 
1763 /**********************************************************************
1764  * eventprob() calculates both what kind of event is the "next" event *
1765  * and what the time is to that event.                                */
eventprob(option_struct * op,data_fmt * data,linlist * alines,tlist * t,brlist ** bigbr,char * event,bseg * brs)1766 double eventprob(option_struct *op, data_fmt *data, linlist *alines,
1767    tlist *t, brlist **bigbr, char *event, bseg *brs)
1768 {
1769 long numilines, numalines;
1770 double pc, pr, pb, tester, tyme, asitesum;
1771 linlist *u;
1772 
1773 if (!alines && (!*bigbr)) {(*event) = '0'; return(0.0);}
1774 
1775 /* number of inactive lineages */
1776 numilines = countinactive(op,t,alines);
1777 
1778 /* count the active lineages and sum active sites */
1779 numalines = 0;
1780 asitesum = 0.0;
1781 for (u = alines; u != NULL; u = u->succ) {
1782    numalines++;
1783    asitesum += u->activesites;
1784 }
1785 
1786 pc = (numalines*(numalines-1) + 2.0*numalines*numilines) / theta0;
1787 pr = asitesum*rec0;
1788 
1789 if (!(*bigbr)) {pb = 0.0; tyme = -log(randum())/(pc + pr);}
1790 else tyme = eventprobbr(op,data,bigbr,t,pc,pr,&pb,brs);
1791 
1792 /* what kind of event? */
1793 if (!pc && !pr && !pb) {(*event) = '0'; return(tyme);}
1794 tester = randum();
1795 if (tester <= pr/(pc+pr+pb)) (*event) = 'r';
1796 else if (tester <= (pc+pr)/(pc+pr+pb)) (*event) = 'c';
1797 else (*event) = 'b';
1798 
1799 return(tyme);
1800 
1801 } /* eventprob */
1802 
1803 
1804 /******************************************************************
1805  * traverse_flagbelow sets the "updated" field of the passed node *
1806  * and all nodes rootwards of it to FALSE.                        */
traverse_flagbelow(tree * tr,node * p)1807 void traverse_flagbelow(tree *tr, node *p)
1808 {
1809 tlist *t;
1810 
1811 for(t = gettymenode(tr,p->number); t != NULL; t = t->succ) {
1812    t->eventnode->updated = FALSE;
1813    if (!istip(t->eventnode)) {
1814       t->eventnode->next->updated = FALSE;
1815       t->eventnode->next->next->updated = FALSE;
1816    }
1817 }
1818 
1819 } /* traverse_flagbelow */
1820 
1821 
1822 /*********************************************************************
1823  * flag_below marks the node "p" iff p is not a tip, and in any case *
1824  *    marks all nodes "rootwards" of p.                              */
flag_below(node * p)1825 void flag_below(node *p)
1826 {
1827 
1828 if (istip(p) && p != curtree->root) flag_below(p->back);
1829 
1830 if(!istip(p)) {
1831    while (p->top) p = p->next;
1832    p->updated = FALSE;
1833    p->next->updated = FALSE;
1834    if(p->next->top) flag_below(p->next->back);
1835    p->next->next->updated = FALSE;
1836    if(p->next->next->top) flag_below(p->next->next->back);
1837 }
1838 } /* flag_below */
1839 
1840 
1841 /*********************************************************************
1842  * traverse_unflag() sets the "updated" field of the passed node and *
1843  * all nodes rootwards of it to TRUE.                                */
traverse_unflag(tree * tr,node * p)1844 void traverse_unflag(tree *tr, node *p)
1845 {
1846 tlist *t;
1847 
1848 for(t = gettymenode(tr,p->number); t != NULL; t = t->succ) {
1849    t->eventnode->updated = TRUE;
1850    if (!istip(t->eventnode)) {
1851       t->eventnode->next->updated = TRUE;
1852       t->eventnode->next->next->updated = TRUE;
1853    }
1854 }
1855 
1856 } /* traverse_unflag */
1857 
1858 
unflag(node * p)1859 void unflag(node *p)
1860 /* remove flags.  call with curtree->root->back. */
1861 {
1862    if(!istip(p)) {
1863      if(!p->next->top) unflag(p->next->back);
1864      if(!p->next->next->top) unflag(p->next->next->back);
1865      p->updated = TRUE;
1866      p->next->updated = TRUE;
1867      p->next->next->updated = TRUE;
1868    }
1869 } /* unflag */
1870 
pickactive(long numalin,linlist ** lineages,node * prohibited)1871 node *pickactive(long numalin, linlist **lineages, node *prohibited)
1872 {
1873   long daughter;
1874   linlist *u;
1875 
1876   do {
1877      daughter = (long)(randum() * numalin) + 1;
1878      u = *lineages;
1879      findlin(&u,daughter);
1880   } while (u->branchtop == prohibited);
1881 
1882   return(u->branchtop);
1883 
1884 } /* pickactive */
1885 
pickinactive(option_struct * op,tlist * t,node * prohibited,linlist * alines)1886 node *pickinactive(option_struct *op, tlist *t, node *prohibited,
1887    linlist *alines)
1888 {
1889 node *daughter;
1890 
1891 do {
1892    daughter = t->branchlist[(long)(randum() * t->numbranch)];
1893 } while (daughter == prohibited || isactive(daughter,alines) ||
1894          (isrecomb(daughter) && isdead(op,daughter)));
1895 
1896 return(daughter);
1897 
1898 } /* pickinactive */
1899 
coalesce(option_struct * op,data_fmt * data,tlist * t,linlist ** lineages,long * lines,double tyme,boolean ** nodenumber,long * numnodes,boolean rootdropping,brlist ** br)1900 void coalesce(option_struct *op, data_fmt *data, tlist *t,
1901    linlist **lineages, long *lines, double tyme, boolean **nodenumber,
1902    long *numnodes, boolean rootdropping, brlist **br)
1903 {
1904   long numalin, numilin, *active1, *active2;
1905   double Pbactive, activelinks;
1906   node *p, *daughter1, *daughter2;
1907   boolean bothactive, rootpick;
1908   dnadata *dna;
1909 
1910   dna = data->dnaptr;
1911 
1912 /* find the number of active (numalin) and inactive (numilin) lineages,
1913    when rootdropping, then the last inactive lineage (the root)
1914    becomes active; leaving no inactive lineages. */
1915   numalin = *lines;
1916   if (!rootdropping) numilin = countinactive(op,t,*lineages);
1917   else numilin = 0;
1918 
1919 
1920   /* pick the 2 lineages to coalesce, daughter1 and daughter2
1921      Pbactive = the chance that they are both active */
1922   Pbactive = (numalin)*(numalin-1) /
1923   ((numalin)*(numalin-1) + 2.0*numalin*numilin);
1924 
1925   if (Pbactive >= randum()) {
1926      daughter1 = pickactive(numalin,lineages,NULL);
1927      daughter2 = pickactive(numalin,lineages,daughter1);
1928      bothactive = TRUE;
1929   } else {
1930      daughter1 = pickactive(numalin,lineages,NULL);
1931      daughter2 = pickinactive(op,t,daughter1,*lineages);
1932      bothactive = FALSE;
1933   }
1934 
1935   rootpick = FALSE;
1936   if (daughter1 == curtree->root->back ||
1937       daughter2 == curtree->root->back)
1938      rootpick = TRUE;
1939 
1940   /* coalesce the two partners */
1941   newnode(&p);
1942   p->number = setnodenumber(nodenumber,numnodes);
1943   p->next->number = p->number;
1944   p->next->next->number = p->number;
1945   p->top = FALSE;
1946   free_x(op,p);
1947   p->next->top = FALSE;
1948   free_x(op,p->next);
1949   p->next->next->top = TRUE;
1950   allocate_x(op,data,p->next->next);
1951   if (op->map) allocate_z(op,data,p->next->next);
1952   ranges_Malloc(p->next->next,TRUE,0L);
1953   p->tyme = tyme;
1954   p->next->tyme = tyme;
1955   p->next->next->tyme = tyme;
1956   p->updated = FALSE;
1957   p->next->updated = FALSE;
1958   p->next->next->updated = FALSE;
1959   p->type = p->next->type = p->next->next->type = 'c';
1960 
1961   curtree->numcoals += 1;
1962   curtree->nodep[p->number] = p->next->next;
1963 
1964   if(!bothactive) {
1965     hookup(p->next->next,daughter2->back);
1966     fixlength(op,data,p->next->next); /* but only if not bothactive! */
1967   }
1968   hookup(p,daughter1);
1969   fixlength(op,data,p);
1970   hookup(p->next,daughter2);
1971   fixlength(op,data,p->next);
1972   if (rootpick) {
1973      hookup(p->next->next,curtree->root);
1974      fixlength(op,data,p->next->next);
1975   }
1976 
1977 /* now set the ranges for the new node */
1978   contrib(op,data,p->next->next,&p->next->next->ranges);
1979 
1980 /* update the tymelist */
1981   /*readdactive(t->succ,daughter1);*/
1982   /*if (bothactive) readdactive(t->succ,daughter2);*/
1983   rembranch(curtree,t->succ,daughter1);
1984   if (bothactive) {
1985      rembranch(curtree,t->succ,daughter2);
1986   }
1987   insertaftertymelist(t,p);
1988   if (bothactive) {
1989      extbranch(curtree,t->succ,p->next->next);
1990   }
1991 
1992 /* now set the coal array for the new node */
1993   if (op->fc) fix_coal(op,data,curtree,t->succ,p);
1994 
1995   sublinlist(lineages,daughter1);
1996   if (bothactive) {
1997     if (op->fc) activelinks = count_activefc(op,data,p->next->next);
1998     else activelinks = count_active(op,data,p->next->next);
1999     addlinlist(lineages,p->next->next, activelinks);
2000     sublinlist(lineages,daughter2);
2001   }
2002   (*lines)--;
2003 
2004   if(!bothactive) {
2005   /* rename the changed branchtop segments */
2006      drop_renamebrlist(br,daughter2,p->next->next);
2007   /* then fix the rest of the ranges and all brlist segments */
2008      if (op->fc) {
2009         active1 = p->next->next->coal;
2010         active2 = daughter2->coal;
2011      } else {
2012         active1 = p->next->next->ranges;
2013         active2 = daughter2->ranges;
2014      }
2015      if(!sameranges(active1,active2))
2016         addbrlist(op,data,br,p->next->next,active2,
2017            active1,NULL,p->next->next->tyme,
2018            p->next->next->back->tyme,FALSE);
2019      drop_brfix(op,data,curtree,t->succ,br);
2020      consolidate_brlist(op,data,curtree,br);
2021   }
2022 
2023 } /* coalesce */
2024 
2025 
2026 /***********************************************************************
2027  * init_numnewactive() sets the numnewactives field for an entire      *
2028  * brlist, removing any brlist segments whose tyme has passed.         */
init_numnewactive(option_struct * op,data_fmt * data,tree * tr,brlist ** bigbr,node * branchtop)2029 void init_numnewactive(option_struct *op, data_fmt *data, tree *tr,
2030    brlist **bigbr, node *branchtop)
2031 {
2032 brlist *br, *brsucc;
2033 
2034 for(br = (*bigbr); br != NULL; br = brsucc) {
2035    brsucc = br->succ;
2036    if (branchtop->tyme >= br->endtyme) {br_remove(bigbr,br); continue;}
2037    if (branchtop->tyme > br->starttyme) {
2038       br->starttyme = branchtop->tyme;
2039       if (br->starttyme >= br->endtyme) {br_remove(bigbr,br); continue;}
2040    }
2041    br->numnewactives = count_activebr(op,data,br);
2042    }
2043 
2044 } /* init_numnewactive */
2045 
2046 
2047 /**********************************************************************
2048  * pickbr_recomb() picks the proper segment to use for re-droping the *
2049  * new lineage, given the tyme at which the drop must occur.  It then *
2050  * removes/truncates appropiately all non-chosen segments in the list.*
2051  * It also picks which site will be the point of crossover.           */
pickbr_recomb(dnadata * dna,brlist ** bigbr,double droptyme,long * cross)2052 brlist *pickbr_recomb(dnadata *dna, brlist **bigbr, double droptyme, long *cross)
2053 {
2054 brlist *br, *brsucc, *start, *picked;
2055 long numbr;
2056 double pick, numactive;
2057 boolean found;
2058 
2059 /* initializations to make lint happy */
2060 start = NULL;
2061 numbr = 0;
2062 numactive = 0.0;
2063 
2064 for(br = (*bigbr); br != NULL; br = brsucc) {
2065    brsucc = br->succ;
2066    if(!isintyme(br,droptyme)) {br_remove(bigbr,br); continue;}
2067    numbr = 0;
2068    numactive = 0.0;
2069    for(start = br; isintyme(br,droptyme); br = br->succ) {
2070       numbr++;
2071       numactive += br->numnewactives;
2072       if (br->succ == NULL) break;
2073    }
2074    break;
2075 }
2076 if (!numbr)
2077    fprintf(ERRFILE,"ERROR:pickbr_recomb failed to do any picking!\n");
2078 
2079 if (!numactive)
2080    fprintf(ERRFILE,"ERROR:pickbr_recomb has no active links!\n");
2081 
2082 
2083 pick = randum() * numactive - start->numnewactives;
2084 for(br = start; pick > 0; br = br->succ) pick -= br->succ->numnewactives;
2085 picked = br;
2086 
2087 numactive = pick+br->numnewactives;
2088 found = FALSE;
2089 
2090 if (br->nfsite < br->ofsite && br->nlsite > br->olsite) {
2091    for(*cross = br->nfsite; *cross < br->ofsite && !found; (*cross)++) {
2092       numactive -= dna->sspace[population][locus][*cross];
2093       if (numactive < 0) {found = TRUE; break;}
2094    }
2095    if (!found)
2096       for(*cross = br->olsite; *cross < br->nlsite && !found;
2097           (*cross)++) {
2098          numactive -= dna->sspace[population][locus][*cross];
2099          if (numactive < 0) {found = TRUE; break;}
2100       }
2101 } else {
2102    if (br->nlsite > br->olsite && br->nfsite < br->olsite)
2103       for(*cross = br->olsite; *cross < br->nlsite && !found;
2104           (*cross)++) {
2105          numactive -= dna->sspace[population][locus][*cross];
2106          if (numactive < 0) {found = TRUE; break;}
2107       }
2108    else
2109       for(*cross = br->nfsite; *cross < br->nlsite && !found;
2110           (*cross)++) {
2111          numactive -= dna->sspace[population][locus][*cross];
2112          if (numactive < 0) {found = TRUE; break;}
2113       }
2114 }
2115 
2116 for(pick = 0, br = start; pick < numbr; pick++, br = brsucc) {
2117    brsucc = br->succ;
2118    if (br != picked) {
2119       if(droptyme < br->endtyme) br->starttyme = droptyme;
2120       else br_remove(bigbr,br);
2121    }
2122 }
2123 
2124 return(picked);
2125 
2126 } /* pickbr_recomb */
2127 
2128 
2129 /*********************************************************************
2130  * boolean brlistrecomb() inserts a new recombination into a partial *
2131  * tree, using a brlist entry as the basis for the recombination.    */
brlistrecomb(option_struct * op,data_fmt * data,tlist * t,linlist ** lineages,long * lines,brlist ** bigbr,double tyme,long * siteptr,boolean ** nodenumber,long * numnodes,bseg * brs)2132 boolean brlistrecomb(option_struct *op, data_fmt *data, tlist *t,
2133    linlist **lineages, long *lines, brlist **bigbr, double tyme,
2134    long *siteptr, boolean **nodenumber, long *numnodes, bseg *brs)
2135 {
2136 long target, numsites;
2137 brlist *br;
2138 node *d, *p;
2139 dnadata *dna;
2140 
2141 dna = data->dnaptr;
2142 numsites = countsites(op,data);
2143 
2144 br = brs->target;
2145 target = brs->cross;
2146 d = br->branchtop;
2147 
2148 /* create recombination node */
2149 newnode(&p);
2150 p->number = setnodenumber(nodenumber,numnodes);
2151 p->next->number = p->number;
2152 p->next->next->number = p->number;
2153 p->top = FALSE;
2154 free_x(op,p);
2155 p->next->top = TRUE;
2156 allocate_x(op,data,p->next);
2157 if(op->map)allocate_z(op,data,p->next);
2158 ranges_Malloc(p->next,TRUE,0L);
2159 p->next->next->top = TRUE;
2160 allocate_x(op,data,p->next->next);
2161 if(op->map)allocate_z(op,data,p->next->next);
2162 ranges_Malloc(p->next->next,TRUE,0L);
2163 p->tyme = tyme;
2164 p->next->tyme = tyme;
2165 p->next->next->tyme = tyme;
2166 p->updated = FALSE;
2167 p->next->updated = FALSE;
2168 p->next->next->updated = FALSE;
2169 p->type = p->next->type = p->next->next->type = 'r';
2170 
2171 curtree->numrecombs += 1;
2172 curtree->nodep[p->number] = p->next;
2173 
2174 hookup(p->next,d->back);
2175 fixlength(op,data,p->next);
2176 hookup(p,d);
2177 fixlength(op,data,p);
2178 fix_rec_ranges(op,data,p);
2179 
2180 /* partition the sites */
2181 if(randum()>0.5) {
2182    p->next->recstart = 0;
2183    p->next->recend = target;
2184    p->next->next->recstart = target + 1;
2185    p->next->next->recend = numsites-1;
2186 } else {
2187    p->next->recstart = target + 1;
2188    p->next->recend = numsites-1;
2189    p->next->next->recstart = 0;
2190    p->next->next->recend = target;
2191 }
2192 
2193 /* now update the ranges for the new node */
2194   contrib(op,data,p->next,&p->next->ranges);
2195   contrib(op,data,p->next->next,&p->next->next->ranges);
2196 
2197 /* update the tymelist */
2198 insertaftertymelist(t,p);
2199 extbranch(curtree,t->succ,p->next->next);
2200 
2201 /* now set the coal arrays */
2202 if (op->fc) fix_coal(op,data,curtree,t->succ,p);
2203 
2204 /* now add brlist stuff for the new node's branch segment */
2205 if (op->fc) addbrlist(op,data,bigbr,p->next,d->coal,p->next->coal,
2206                NULL,p->next->tyme,p->next->back->tyme,FALSE);
2207 else addbrlist(op,data,bigbr,p->next,d->ranges,p->next->ranges,
2208         NULL,p->next->tyme,p->next->back->tyme,FALSE);
2209 
2210 
2211 /* fix alias entries */
2212 if (op->datatype == 'n' || op->datatype == 's')
2213    edit_alias(op,data,siteptr,target);
2214 
2215 /* add new entry to linlist */
2216 if (op->fc) addlinlist(lineages,p->next->next,
2217    count_activefc(op,data,p->next->next));
2218 else addlinlist(lineages,p->next->next,count_active(op,data,p->next->next));
2219 (*lines)++;
2220 
2221 if (tyme < br->endtyme) br->starttyme = tyme;
2222 drop_renamebrlist(bigbr,br->branchtop,p->next);
2223 drop_brfix(op,data,curtree,t->succ,bigbr);
2224 consolidate_brlist(op,data,curtree,bigbr);
2225 
2226 if (curtree->numrecombs > RECOMB_MAX) return(FALSE);
2227 return(TRUE);
2228 
2229 } /* brlistrecomb */
2230 
2231 
2232 /********************************************************************
2233  * choosepsite() chooses the sequence site that a new recombination *
2234  * will start at.                                                   */
choosepsite(option_struct * op,data_fmt * data,node * p,double targetlink)2235 long choosepsite(option_struct *op, data_fmt *data, node *p,
2236    double targetlink)
2237 {
2238 long target;
2239 
2240 
2241 for(target = p->ranges[1]; target < p->ranges[2*p->ranges[0]]; target++) {
2242    if (op->datatype == 'n') targetlink--;
2243    else targetlink -= getdata_space(op,data,target);
2244    if (targetlink <= 0) break;
2245 }
2246 
2247 if (target == p->ranges[2*p->ranges[0]]) {
2248    fprintf(ERRFILE,"ERROR:choosepsite: failure to choose %ld %ld\n",indecks,
2249       apps);
2250 }
2251 
2252 return(target);
2253 
2254 } /* choosepsite */
2255 
2256 
2257 /**********************************************************************
2258  * choosepsitefc() chooses the sequence site that a new recombination *
2259  * will start at.                                                     */
choosepsitefc(option_struct * op,data_fmt * data,node * p,double targetlink)2260 long choosepsitefc(option_struct *op, data_fmt *data, node *p,
2261    double targetlink)
2262 {
2263 long target;
2264 
2265 for(target = p->coal[1]; target < p->coal[2*p->coal[0]]; target++) {
2266    if (op->datatype == 'n') targetlink--;
2267    else targetlink -= getdata_space(op,data,target);
2268    if (targetlink <= 0) break;
2269 }
2270 
2271 if (target == p->coal[2*p->coal[0]]) {
2272    fprintf(ERRFILE,"ERROR:choosepsitefc: failure to choose %ld %ld\n",indecks,
2273       apps);
2274 }
2275 
2276 return(target);
2277 
2278 } /* choosepsite */
2279 
2280 
recomb(option_struct * op,data_fmt * data,tlist * t,linlist ** lineages,long * lines,double tyme,long * siteptr,boolean ** nodenumber,long * numnodes)2281 boolean recomb(option_struct *op, data_fmt *data, tlist *t,
2282   linlist **lineages, long *lines, double tyme, long *siteptr,
2283   boolean **nodenumber, long *numnodes)
2284 {
2285   long target, numsites;
2286   double ntarget, numactive;
2287   linlist *u;
2288   node *d, *p;
2289   boolean rootpick;
2290   dnadata *dna;
2291 
2292   dna = data->dnaptr;
2293   numsites = countsites(op,data);
2294 
2295   u = *lineages;
2296   /* find splitting lineage, which must be active */
2297   /* we first count up all active sites on active lineages -- */
2298   numactive = 0;
2299   do {
2300     numactive += u->activesites;
2301     u = u->succ;
2302   } while (u != NULL);
2303   /* -- then we choose a lineage proportional to the active sites */
2304   ntarget = randum()*numactive;
2305   numactive = 0;
2306   u = *lineages;
2307   do {
2308     numactive += u->activesites;
2309     if (u->activesites != 0 && numactive >= ntarget) break;
2310     u = u->succ;
2311   } while(1);
2312   d = u->branchtop;
2313 
2314   rootpick = FALSE;
2315   if (d == curtree->root->back) rootpick = TRUE;
2316 
2317 /* create recombination node */
2318   newnode(&p);
2319   p->number = setnodenumber(nodenumber,numnodes);
2320   p->next->number = p->number;
2321   p->next->next->number = p->number;
2322   p->top = FALSE;
2323   free_x(op,p);
2324   p->next->top = TRUE;
2325   allocate_x(op,data,p->next);
2326   if(op->map)allocate_z(op,data,p->next);
2327   ranges_Malloc(p->next,TRUE,0L);
2328   p->next->next->top = TRUE;
2329   allocate_x(op,data,p->next->next);
2330   if(op->map)allocate_z(op,data,p->next->next);
2331   ranges_Malloc(p->next->next,TRUE,0L);
2332   p->tyme = tyme;
2333   p->next->tyme = tyme;
2334   p->next->next->tyme = tyme;
2335   p->updated = FALSE;
2336   p->next->updated = FALSE;
2337   p->next->next->updated = FALSE;
2338   p->type = p->next->type = p->next->next->type = 'r';
2339 
2340   curtree->numrecombs += 1;
2341   curtree->nodep[p->number] = p->next;
2342 
2343   hookup(p,d);
2344   fixlength(op,data,p);
2345   if (rootpick) {
2346      hookup(p->next,curtree->root);
2347      fixlength(op,data,p->next);
2348   }
2349 
2350 /* partition the sites */
2351   numactive = randum()*u->activesites;
2352   if (op->fc) target = choosepsitefc(op,data,d,numactive);
2353   else target = choosepsite(op,data,d,numactive);
2354   if(randum()>0.5) {
2355     p->next->recstart = 0;
2356     p->next->recend = target;
2357     p->next->next->recstart = target+1;
2358     p->next->next->recend = numsites-1;
2359   } else {
2360     p->next->recstart = target+1;
2361     p->next->recend = numsites-1;
2362     p->next->next->recstart = 0;
2363     p->next->next->recend = target;
2364   }
2365 
2366 /* set the ranges fields for the 2 rootwards branches */
2367   contrib(op,data,p->next,&p->next->ranges);
2368   contrib(op,data,p->next->next,&p->next->next->ranges);
2369 
2370   /* update the tymelist */
2371   /*readdactive(t->succ,d);*/
2372   rembranch(curtree,t->succ,d);
2373   insertaftertymelist(t,p);
2374   extbranch(curtree,t->succ,p->next->next);
2375   extbranch(curtree,t->succ,p->next);
2376 
2377 /* set the coal fields for the 2 rootwards branches */
2378   if (op->fc) fix_coal(op,data,curtree,t->succ,p);
2379 
2380 /* fix alias entries */
2381   if (op->datatype == 'n' || op->datatype == 's')
2382      edit_alias(op,data,siteptr,target+1);
2383 
2384 /* remove old entry from linlist */
2385   sublinlist(lineages,d);
2386 
2387 /* add two new entries to linlist */
2388   if (op->fc) {
2389      addlinlist(lineages,p->next,count_activefc(op,data,p->next));
2390      addlinlist(lineages,p->next->next,count_activefc(op,data,p->next->next));
2391   } else {
2392      addlinlist(lineages,p->next,count_active(op,data,p->next));
2393      addlinlist(lineages,p->next->next,count_active(op,data,p->next->next));
2394   }
2395   (*lines)++;
2396 
2397   if (curtree->numrecombs > RECOMB_MAX) return(FALSE);
2398   return(TRUE);
2399 } /* recomb */
2400 
2401 
find_rootloop(tlist * start,tlist ** found)2402 boolean find_rootloop(tlist *start, tlist **found)
2403 {
2404 tlist *t;
2405 
2406 for (t = start; t != NULL; t = t->succ)
2407    if (t->numbranch == 1)
2408       if (t->eventnode != curtree->root->back) {
2409          (*found) = t;
2410          return(TRUE);
2411       }
2412 
2413 (*found) = NULL;
2414 return(FALSE);
2415 
2416 } /* find_rootloop */
2417 
2418 
2419 /******************************************************************
2420  * free_from_tymelist truncates the tymelist starting at argument *
2421  * "start", then cleans up the revenant time slices.              */
free_from_tymelist(tlist * start)2422 void free_from_tymelist(tlist *start)
2423 {
2424 tlist *t, *temp;
2425 
2426 start->prev->succ = NULL;
2427 
2428 for (t = start; t != NULL; t = temp) {
2429    temp = t->succ;
2430    if (isrecomb(t->eventnode)) curtree->numrecombs--;
2431    else curtree->numcoals--;
2432    fix_treenodep(curtree,t->eventnode->number);
2433    freenode(t->eventnode);
2434    freetymenode(t);
2435 }
2436 
2437 } /* free_from_tymelist */
2438 
2439 
2440 /***********************************************************************
2441  * update_rangecoal() updates all ranges and coal arrays in the passed *
2442  * in tree.  It assumes that both the tree and tymelist are correct.   */
update_rangecoal(option_struct * op,data_fmt * data,tree * tr)2443 void update_rangecoal(option_struct *op, data_fmt *data, tree *tr)
2444 {
2445 tlist *t;
2446 node *p;
2447 
2448 for(t = tr->tymelist->succ; t != NULL; t = t->succ) {
2449    p = findunique(t->eventnode);
2450    if (isrecomb(p)) {
2451       fix_rec_ranges(op,data,p);
2452    } else {
2453       fix_coal_ranges(op,data,p);
2454    }
2455    if (op->fc) fix_coal(op,data,tr,t,p);
2456 }
2457 
2458 } /* update_rangecoal */
2459 
2460 
remove_rootloop(option_struct * op,data_fmt * data,long * sp)2461 void remove_rootloop(option_struct *op, data_fmt *data, long *sp)
2462 {
2463 tlist *t;
2464 dnadata *dna;
2465 
2466 dna = data->dnaptr;
2467 
2468 if (curtree->numrecombs == 0) return;
2469 
2470 if (find_rootloop(curtree->tymelist,&t)) {
2471    hookup(t->eventnode,curtree->root);
2472    t->age = ROOTLENGTH + t->eventnode->tyme;
2473    curtree->root->tyme = t->age;
2474    curtree->root->back->length = ROOTLENGTH;
2475    ltov(op,data,curtree->root->back);
2476    free_from_tymelist(t->succ);
2477    if (op->datatype == 'n' || op->datatype == 's')
2478       rebuild_alias(op,data,sp);
2479 }
2480 
2481 } /* remove_rootloop */
2482 
2483 
remove_deadrecombs(option_struct * op,data_fmt * data,tree * tr)2484 void remove_deadrecombs(option_struct *op, data_fmt *data, tree *tr)
2485 {
2486 long deadcount;
2487 node *p;
2488 tlist *t;
2489 
2490 if (tr->numrecombs < 2) return;
2491 
2492 deadcount = 0;
2493 for(t = tr->tymelist; t->succ != NULL; t = t->succ) ;
2494 for(; t != NULL; t = t->prev) {
2495    p = findunique(t->eventnode);
2496    if (isrecomb(p)) {
2497       if (isdead(op,p->next)) {
2498          remove_pairednodes(op,data,tr,p,p->next);
2499          deadcount++;
2500          for(t = tr->tymelist; t->succ != NULL; t = t->succ) ;
2501       } else {
2502          if (isdead(op,p->next->next)) {
2503               remove_pairednodes(op,data,tr,p,p->next->next);
2504               deadcount++;
2505               for(t = tr->tymelist; t->succ != NULL; t = t->succ) ;
2506            }
2507       }
2508    }
2509 }
2510 
2511 if (deadcount) update_rangecoal(op,data,tr);
2512 
2513 } /* remove_deadrecombs */
2514 
2515 
2516 /*********************************************************************
2517  * remove_excess_tree() removes "dead" branches from the tree:       *
2518  *    all rootloops are removed, all nodes and branches after the    *
2519  *        total number of branches in an interval has reached 1,     *
2520  *    all branches that no longer contain any "live" sites, those    *
2521  *        sites that eventually reach a tip.                         *
2522  *                                                                   *
2523  * Note: these two procedures destroy the exact correspondence       *
2524  * the "nodep" array and the tree, renumber_nodes() should be called *
2525  * aftercalling this proceedure.                                     */
remove_excess_tree(option_struct * op,data_fmt * data,tree * tr,long * siteptr)2526 void remove_excess_tree(option_struct *op, data_fmt *data, tree *tr,
2527    long *siteptr)
2528 {
2529 remove_deadrecombs(op,data,tr);
2530 remove_rootloop(op,data,siteptr);
2531 } /* remove_excess_tree */
2532 
2533 
counttymelist(tlist * t)2534 long counttymelist(tlist *t)
2535 /* count number of entries in tymelist */
2536 {
2537   long cntr;
2538 
2539   cntr = 0;
2540   do {
2541      cntr++;
2542      t = t->succ;
2543   } while (t!=NULL);
2544   return(cntr);
2545 } /* counttymelist */
2546 
2547 
rootdrop(option_struct * op,data_fmt * data,tlist * t,double starttyme,linlist ** lineages,long * lines,long * siteptr,boolean ** nodenumber,long * numnodes,brlist ** br)2548 boolean rootdrop(option_struct *op, data_fmt *data, tlist *t, double starttyme, linlist **lineages,
2549    long *lines, long *siteptr, boolean **nodenumber, long *numnodes,
2550    brlist **br)
2551 {
2552 double basetyme, newtyme;
2553 char eventtype;
2554 boolean not_aborted;
2555 node *p;
2556 
2557 /* if necessary, add the root to the active lineages */
2558 if (!foundlin(*lineages,curtree->root->back)) {
2559    if (op->fc)
2560       addlinlist(lineages,curtree->root->back,
2561          count_activefc(op,data,curtree->root->back));
2562    else
2563       addlinlist(lineages,curtree->root->back,
2564          count_active(op,data,curtree->root->back));
2565    (*lines)++;
2566 }
2567 
2568 basetyme = starttyme;
2569 p = curtree->root->back;
2570 not_aborted = TRUE;
2571 delete_brlist(br);
2572 
2573 while (*lines > 1) {
2574    newtyme = basetyme + eventprob(op,data,*lineages,t,br,&eventtype,NULL);
2575    switch ((int)eventtype) {
2576       case 'c' :
2577          coalesce(op,data,t,lineages,lines,newtyme,nodenumber,
2578             numnodes,TRUE,br);
2579          break;
2580       case 'r' :
2581          not_aborted = recomb(op,data,t,lineages,lines,
2582             newtyme,siteptr,nodenumber,numnodes);
2583          break;
2584       case 'b' :
2585          fprintf(ERRFILE,"ERROR:rootdrop case b: can't get here\n");
2586          break;
2587       case '0' :
2588          fprintf(ERRFILE,"ERROR:rootdrop case 0: can't get here\n");
2589          break;
2590       default :
2591          fprintf(ERRFILE,"ERROR:rootdrop case: can't get here\n");
2592          break;
2593       }
2594    if (!not_aborted) break;
2595    t = t->succ;
2596    basetyme = newtyme;
2597 
2598 }
2599 
2600 
2601 if (not_aborted) traverse_flagbelow(curtree,p);
2602 return(not_aborted);
2603 
2604 } /* rootdrop */
2605 
2606 
pickbranch(option_struct * op,data_fmt * data,tree * source,tlist ** tymeslice,double * offset)2607 node *pickbranch(option_struct *op, data_fmt *data, tree *source,
2608    tlist **tymeslice, double *offset)
2609 {
2610 long branch, numbranches;
2611 node *p;
2612 tlist *t;
2613 
2614 (*offset) = 0.0;
2615 numbranches = countbranches(op,data,source);
2616 
2617 branch = (long)(randum() * numbranches) + 1;
2618 
2619 if (branch <= getdata_numtips(op,data)) {
2620    if (tymeslice) (*tymeslice) = source->tymelist;
2621    return(source->nodep[branch]);
2622 }
2623 branch -= getdata_numtips(op,data);
2624 
2625 for (t = source->tymelist->succ; t != NULL; t = t->succ) {
2626    branch -= (isrecomb(t->eventnode) ? 2 : 1);
2627    if (branch < 1) {
2628       (*tymeslice) = t;
2629       p = findunique(t->eventnode);
2630       if (isrecomb(p))
2631          return((randum() < 0.5) ? p->next : p->next->next);
2632       else
2633          return(findtop(p));
2634    }
2635 }
2636 
2637 fprintf(ERRFILE,"ERROR:pickbranch--failure to find branch\n");
2638 return(NULL);
2639 
2640 } /* pickbranch */
2641 
2642 
renumber_nodes(option_struct * op,data_fmt * data,tree * trii)2643 void renumber_nodes(option_struct *op, data_fmt *data, tree *trii)
2644 {
2645 tlist *t;
2646 long nodenumber;
2647 
2648 /* since the root is "0", the first non-tip node will be "numseq+1" */
2649 nodenumber = getdata_numtips(op,data) + 1;
2650 
2651 for (t = trii->tymelist->succ; t != NULL; t = t->succ) {
2652    t->eventnode->number = nodenumber;
2653    t->eventnode->next->number = nodenumber;
2654    t->eventnode->next->next->number = nodenumber;
2655    trii->nodep[nodenumber] = t->eventnode;
2656    nodenumber++;
2657 }
2658 
2659 } /* renumber_nodes */
2660 
finishbadtree(option_struct * op,data_fmt * data,tree * tr,linlist ** lineages,long * numlins,boolean ** nodenumber,long * numnodes,boolean rootdropped,brlist ** brlines)2661 void finishbadtree(option_struct *op, data_fmt *data, tree *tr, linlist **lineages, long *numlins,
2662    boolean **nodenumber, long *numnodes, boolean rootdropped,
2663    brlist **brlines)
2664 {
2665 double ntyme;
2666 tlist *t;
2667 
2668 /* go to the end of the tymelist */
2669 for(t = tr->tymelist; t->succ != NULL; t = t->succ) ;
2670 
2671 while (*numlins > 1) {
2672    ntyme = t->eventnode->tyme + 0.01;
2673    coalesce(op,data,t,lineages,numlins,ntyme,nodenumber,numnodes,rootdropped,
2674       brlines);
2675    t = t->succ;
2676 }
2677 delete_brlist(brlines);
2678 
2679 } /* finishbadtree */
2680 
2681 
2682 /***********************************************************
2683  * initbrlist() allocates and initializes a brlist element */
initbrlist(node * branchtop,double starttyme,double endtyme,long numsites)2684 brlist *initbrlist(node *branchtop, double starttyme, double endtyme,
2685    long numsites)
2686 {
2687 brlist *newbr;
2688 
2689 newbr = (brlist *)calloc(1,sizeof(brlist));
2690 newbr->branchtop = branchtop;
2691 newbr->segranges = (int *)calloc(numsites,sizeof(int));
2692 newbr->starttyme = starttyme;
2693 newbr->endtyme = endtyme;
2694 newbr->updated = FALSE;
2695 
2696 return(newbr);
2697 
2698 } /* initbrlist */
2699 
2700 
2701 /**************************************************
2702  * freebrlist() just frees an element of a brlist */
freebrlist(brlist * br)2703 void freebrlist(brlist *br)
2704 {
2705 
2706 free(br->segranges);
2707 free(br);
2708 
2709 } /* freebrlist */
2710 
2711 
2712 /*********************************************************
2713  * delete_brlist() deletes an entire brlist, setting the *
2714  * base pointer to NULL.                                 */
delete_brlist(brlist ** bigbr)2715 void delete_brlist(brlist **bigbr)
2716 {
2717 brlist *br, *brsucc;
2718 
2719 if (!bigbr) return;
2720 
2721 for(br = (*bigbr); br != NULL; br = brsucc) {
2722    brsucc = br->succ;
2723    br_remove(bigbr,br);
2724 }
2725 
2726 (*bigbr) = NULL;
2727 
2728 } /* delete_brlist */
2729 
2730 
2731 /******************************************************************
2732  * hookup_brlist() mechanically adds a new element into a brlist. *
2733  * New elements are inserted so that the list stays time-sorted   *
2734  * (least to greatest).                                           */
hookup_brlist(brlist ** bigbr,brlist * newbr)2735 void hookup_brlist(brlist **bigbr, brlist *newbr)
2736 {
2737 brlist *br;
2738 
2739 if (!*bigbr) { /* new list being created */
2740    (*bigbr) = newbr;
2741    newbr->succ = newbr->prev = NULL;
2742 } else {
2743    br = getbrlistbytyme((*bigbr),newbr->starttyme);
2744    if (!br) { /* adding to end of list */
2745       for (br = (*bigbr); br->succ != NULL; br = br->succ)
2746          ;
2747       br->succ = newbr;
2748       newbr->prev = br;
2749       newbr->succ = NULL;
2750    } else {
2751       newbr->succ = br;
2752       newbr->prev = br->prev;
2753       if (br->prev) br->prev->succ = newbr;
2754       br->prev = newbr;
2755       if (*bigbr == br) (*bigbr) = newbr;
2756    }
2757 }
2758 
2759 } /* hookup_brlist */
2760 
2761 
2762 /*******************************************************************
2763  * set_sitesbr() sets the "sites" information for a brlist segment */
set_sitesbr(option_struct * op,data_fmt * data,brlist * br)2764 void set_sitesbr(option_struct *op, data_fmt *data, brlist *br)
2765 {
2766 long i, numsites;
2767 boolean done1, done2;
2768 
2769 numsites = countsites(op,data);
2770 
2771 done1 = FALSE;
2772 done2 = FALSE;
2773 
2774 br->nfsite = numsites;
2775 br->ofsite = numsites;
2776 
2777 for (i = 0; i < numsites; i++) {
2778    if (!done1)
2779       if (br->segranges[i] >= 1) {
2780          br->nfsite = i;
2781          done1 = TRUE;
2782          }
2783    if (!done2)
2784       if (br->segranges[i] == -1 ||
2785           br->segranges[i] == 2) {
2786          br->ofsite = i;
2787          done2 = TRUE;
2788          }
2789    if (done1 && done2) break;
2790 }
2791 
2792 done1 = FALSE;
2793 done2 = FALSE;
2794 
2795 br->nlsite = br->nfsite - 1;
2796 br->olsite = br->ofsite - 1;
2797 
2798 for (i = numsites-1; i >= 0; i--) {
2799    if (!done1)
2800       if (br->segranges[i] >= 1) {
2801           br->nlsite = i;
2802           done1 = TRUE;
2803           }
2804    if (!done2)
2805       if (br->segranges[i] == -1 ||
2806           br->segranges[i] == 2) {
2807           br->olsite = i;
2808           done2 = TRUE;
2809           }
2810    if (done1 && done2) break;
2811 }
2812 
2813 } /* set_sitesbr */
2814 
2815 
2816 /***************************************************************
2817  * count_activebr() returns the number of active links present *
2818  * in a brlist segment.                                        */
count_activebr(option_struct * op,data_fmt * data,brlist * br)2819 double count_activebr(option_struct *op, data_fmt *data, brlist *br)
2820 {
2821 
2822 if (!br->updated) {
2823    set_sitesbr(op,data,br);
2824    br->updated = TRUE;
2825    }
2826 
2827 if (br->nfsite == countsites(op,data)) return(0L);
2828 
2829 if (br->olsite <= br->nfsite || br->ofsite >= br->nlsite) {
2830    return(getnumlinks(op,data,br->nfsite,br->nlsite));
2831 }
2832 
2833 if (br->nfsite < br->ofsite && br->nlsite > br->olsite) {
2834    return(getnumlinks(op,data,br->nfsite,br->ofsite) +
2835        getnumlinks(op,data,br->olsite,br->nlsite));
2836 }
2837 
2838 if (br->nfsite < br->ofsite) {
2839    return(getnumlinks(op,data,br->nfsite,br->ofsite));
2840 }
2841 
2842 if (br->nlsite > br->olsite) {
2843    return(getnumlinks(op,data,br->olsite,br->nlsite));
2844 }
2845 
2846 return(0.0);
2847 
2848 
2849 } /* count_activebr */
2850 
2851 
2852 /***************************************************************
2853  * isintyme() checks to see if a given tyme is within the range *
2854  * covered by a particular brlist entry.                       */
isintyme(brlist * br,double target)2855 boolean isintyme(brlist *br, double target)
2856 {
2857 
2858 return((target >= br->starttyme) && (target <= br->endtyme) ?
2859           TRUE : FALSE);
2860 
2861 } /* isintyme */
2862 
2863 
2864 /******************************************************************
2865  * getbrlistbystart() returns a pointer to the brlist entry which *
2866  * contains the nodelet; returning NULL if nothing is found.      */
getbrlistbystart(brlist * start,node * target,double starttyme)2867 brlist *getbrlistbystart(brlist *start, node *target, double starttyme)
2868 {
2869 brlist *br;
2870 long match;
2871 
2872 for(br = start; br != NULL; br = br->succ) {
2873    match = sametreebranch(br,target,starttyme,BOGUSTREETYME);
2874    if (match == 1 || match == 2) return(br);
2875 }
2876 
2877 return(NULL);
2878 
2879 } /* getbrlistbystart */
2880 
2881 
2882 /****************************************************************
2883  * getbrlistbyend() returns a pointer to the brlist entry which *
2884  * contains the nodelet; returning NULL if nothing is found.    */
getbrlistbyend(brlist * start,node * target,double endtyme)2885 brlist *getbrlistbyend(brlist *start, node *target, double endtyme)
2886 {
2887 brlist *br;
2888 long match;
2889 
2890 for(br = start; br != NULL; br = br->succ) {
2891    match = sametreebranch(br,target,BOGUSTREETYME,endtyme);
2892    if (match == -1 || match == 2) return(br);
2893 }
2894 
2895 return(NULL);
2896 
2897 } /* getbrlistbyend */
2898 
2899 
2900 /********************************************************************
2901  * getbrlistbytyme() finds the first element in a brlist that has a *
2902  * starttyme >= the searchtyme, returning NULL if nothing is found. */
getbrlistbytyme(brlist * start,double searchtyme)2903 brlist *getbrlistbytyme(brlist *start, double searchtyme)
2904 {
2905 brlist *br;
2906 
2907 for(br = start; br != NULL; br = br->succ)
2908    if (br->starttyme >= searchtyme) return(br);
2909 
2910 return(NULL);
2911 
2912 } /* getbrlistbytyme */
2913 
2914 
2915 /*******************************************************
2916  * updatesegranges() updates the segranges of a brlist *
2917  * given the passed arrays.                            *
2918  *                                                     *
2919  * segranges is 0 if site has remained dead            *
2920  *           is +1 for becoming live                   *
2921  *           is -1 for becoming dead                   *
2922  *           is +2 for remaining alive                 */
updatesegranges(option_struct * op,data_fmt * data,brlist * br,int * oldsegranges,long * oldranges,long * newranges)2923 void updatesegranges(option_struct *op, data_fmt *data, brlist *br,
2924    int *oldsegranges, long *oldranges, long *newranges)
2925 {
2926 long i, newi, newstart, newend, numsites;
2927 
2928 long oldind, newind, cstart, cend, csize, oval, nval;
2929 boolean oldlive, newlive;
2930 dnadata *dna;
2931 int *bstart;
2932 
2933 br->updated = FALSE;
2934 
2935 numsites = countsites(op,data);
2936 
2937 if (!oldranges && !newranges && oldsegranges) {
2938    memcpy(br->segranges,oldsegranges,numsites*sizeof(int));
2939    return;
2940 }
2941 
2942 dna = data->dnaptr;
2943 newi = 1;
2944 newstart = newranges[newi];
2945 if (newstart == FLAGLONG) {
2946    newstart = numsites;
2947    newend = numsites;
2948 } else newend = newranges[newi+1];
2949 if (oldranges) {
2950 if (oldranges[0]) {
2951    oldlive = FALSE;
2952    newlive = FALSE;
2953    oldind = newind = 1;
2954    oval = oldranges[oldind];
2955    nval = ((newstart != numsites) ? newranges[newind] : numsites);
2956    cstart = 0;
2957    cend = ((nval < oval) ? nval : oval);
2958    while (1) {
2959       csize = cend - cstart;
2960       bstart = &(br->segranges[cstart]);
2961       if (csize) {
2962          if (oldlive && newlive)
2963            memcpy(bstart,dna->segranges2,csize*sizeof(int));
2964          else if (!oldlive && newlive)
2965            memcpy(bstart,dna->segranges1,csize*sizeof(int));
2966          else if (!oldlive && !newlive)
2967            memcpy(bstart,dna->segranges0,csize*sizeof(int));
2968          else if (oldlive && !newlive)
2969            memcpy(bstart,dna->segranges3,csize*sizeof(int));
2970       }
2971       if (cend == numsites) break;
2972       if (oval == cend) {
2973          oldind++;
2974          oldlive = !oldlive;
2975          if (oldlive) oval = oldranges[oldind] + 1;
2976          else oval = oldranges[oldind];
2977          if (oval == FLAGLONG)
2978             oval = numsites;
2979       }
2980       if (nval == cend) {
2981          newind++;
2982          newlive = !newlive;
2983          if (newlive) nval = newranges[newind] + 1;
2984          else nval = newranges[newind];
2985          if (nval == FLAGLONG)
2986             nval = numsites;
2987       }
2988       cstart = cend;
2989       cend = (nval < oval) ? nval : oval;
2990    }
2991 }
2992 } else {
2993    for(i = 0; i < numsites; i++) {
2994       if (i > newend) {
2995          newi+=2;
2996          if (newranges[newi] == FLAGLONG) {
2997             newstart = numsites;
2998             newend = numsites;
2999          } else {
3000             newstart = newranges[newi];
3001             newend = newranges[newi+1];
3002          }
3003       }
3004       if (i >= newstart && i <= newend) {
3005          if (oldsegranges[i] == 0) br->segranges[i] = 1;
3006          else if (oldsegranges[i] == -1) br->segranges[i] = 2;
3007          else br->segranges[i] = oldsegranges[i];
3008      } else {
3009          if (oldsegranges[i] == 2) br->segranges[i] = -1;
3010          else if (oldsegranges[i] == 1) br->segranges[i] = 0;
3011          else br->segranges[i] = oldsegranges[i];
3012      }
3013 
3014    }
3015 }
3016 
3017 } /* updatesegranges */
3018 
3019 
3020 /************************************************************
3021  * segranges_to_ranges() converts from segranges to ranges. *
3022  *                                                          *
3023  * This code may be wrong--it converts segranges to current *
3024  * range info, not the original?                            */
segranges_to_ranges(int * segranges,long ** ranges,long numsites)3025 void segranges_to_ranges(int *segranges, long **ranges, long numsites)
3026 {
3027 long i, newstart, newend;
3028 boolean live;
3029 
3030 /* initialization for lint */
3031 newend = 0;
3032 
3033 for(i = 0, newstart = FLAGLONG, live = FALSE; i < numsites; i++) {
3034    if((!live && (segranges[i] == -1 || segranges == 0)) ||
3035      (live && (segranges[i] == 1 || segranges[i] == 2)))
3036       continue;
3037    live = !live;
3038    if(live) {newstart = i; newend = FLAGLONG;}
3039    if(!live) newend = i-1;
3040    if(newstart != FLAGLONG && newend != FLAGLONG) {
3041       addrange(ranges,newstart,newend);
3042       newstart = FLAGLONG;
3043    }
3044 }
3045 
3046 } /* segranges_to_ranges */
3047 
3048 
3049 /*********************************************************
3050  * addbrlist() adds an element to an existing brlist and *
3051  * depends on both the tree and tymelist being correct   *
3052  * from the tips to the tyme of the nodelet newtop.      */
addbrlist(option_struct * op,data_fmt * data,brlist ** bigbr,node * newtop,long * oldranges,long * newranges,int * segranges,double starttyme,double endtyme,boolean building)3053 void addbrlist(option_struct *op, data_fmt *data, brlist **bigbr,
3054    node *newtop, long *oldranges, long *newranges, int *segranges,
3055    double starttyme, double endtyme, boolean building)
3056 {
3057 double oldendtyme;
3058 int *tsegranges, *oldsegs;
3059 brlist *tnewbr, *bnewbr, *newbr;
3060 long numsites;
3061 
3062 numsites = countsites(op,data);
3063 if (starttyme == endtyme || !newtop) return;
3064 
3065 tnewbr = getbrlistbystart(*bigbr,newtop,starttyme);
3066 bnewbr = getbrlistbyend(*bigbr,newtop,endtyme);
3067 
3068 if (!tnewbr && !bnewbr) {
3069    newbr = initbrlist(newtop,starttyme,endtyme,countsites(op,data));
3070    if (oldranges && newranges) {
3071       updatesegranges(op,data,newbr,NULL,oldranges,newranges);
3072    } else {
3073       updatesegranges(op,data,newbr,segranges,NULL,NULL);
3074    }
3075    hookup_brlist(bigbr,newbr);
3076    return;
3077 }
3078 
3079 /* we have the same start & end */
3080 if (tnewbr && bnewbr) {
3081    if (tnewbr->endtyme == endtyme) { /* we have the same segment */
3082       if (newranges) {
3083          if (building) {
3084             updatesegranges(op,data,tnewbr,NULL,oldranges,newranges);
3085          } else {
3086             updatesegranges(op,data,tnewbr,tnewbr->segranges,NULL,newranges);
3087          }
3088       } else {
3089          updatesegranges(op,data,tnewbr,segranges,NULL,NULL);
3090       }
3091    } else {
3092       if (newranges) {
3093          for(; ; tnewbr = tnewbr->succ) {
3094             if (tnewbr->branchtop != bnewbr->branchtop) continue;
3095             if (building) {
3096                updatesegranges(op,data,tnewbr,NULL,oldranges,newranges);
3097             } else {
3098                updatesegranges(op,data,tnewbr,tnewbr->segranges,NULL,
3099                   newranges);
3100             }
3101          if (tnewbr == bnewbr) break;
3102          if (tnewbr->endtyme != bnewbr->starttyme)
3103             addbrlist(op,data,bigbr,newtop,oldranges,newranges,segranges,
3104                tnewbr->endtyme,bnewbr->starttyme,building);
3105          }
3106       }
3107    }
3108    return;
3109 }
3110 
3111 /* we only have the same start */
3112 if (tnewbr) {
3113    oldendtyme = tnewbr->endtyme;
3114    if (oldendtyme > endtyme) {
3115       tnewbr->starttyme = endtyme;
3116       addbrlist(op,data,bigbr,newtop,oldranges,newranges,segranges,
3117          starttyme,endtyme,building);
3118    } else {
3119       updatesegranges(op,data,tnewbr,tnewbr->segranges,NULL,newranges);
3120       addbrlist(op,data,bigbr,newtop,oldranges,newranges,segranges,
3121          oldendtyme,endtyme,building);
3122       }
3123    return;
3124 } else { /* we only have the same end */
3125    if (starttyme > bnewbr->starttyme) {
3126       bnewbr->endtyme = starttyme;
3127       oldsegs = (int *)calloc(numsites,sizeof(int));
3128       memcpy(oldsegs,bnewbr->segranges,numsites*sizeof(int));
3129       updatesegranges(op,data,bnewbr,bnewbr->segranges,NULL,newranges);
3130       tsegranges = (int *)calloc(numsites,sizeof(int));
3131       memcpy(tsegranges,bnewbr->segranges, numsites*sizeof(int));
3132       memcpy(bnewbr->segranges,oldsegs,numsites*sizeof(int));
3133       addbrlist(op,data,bigbr,newtop,NULL,NULL,tsegranges,starttyme,
3134          endtyme,building);
3135       free(oldsegs);
3136       free(tsegranges);
3137    } else {
3138       addbrlist(op,data,bigbr,newtop,oldranges,newranges,segranges,
3139          starttyme,bnewbr->starttyme,building);
3140       updatesegranges(op,data,bnewbr,bnewbr->segranges,NULL,newranges);
3141    }
3142    return;
3143 }
3144 
3145 } /* addbrlist */
3146 
3147 
makeevent(option_struct * op,data_fmt * data,tree * growtree,tlist * tymeslice,brlist ** brlines,linlist ** alines,long * numalines,double newtyme,boolean ** nodenumber,long * numnodes,long * siteptr,char eventtype,boolean rootdropped,bseg * brs)3148 boolean makeevent(option_struct *op, data_fmt *data, tree *growtree,
3149    tlist *tymeslice, brlist **brlines, linlist **alines, long *numalines,
3150    double newtyme, boolean **nodenumber, long *numnodes, long *siteptr,
3151    char eventtype, boolean rootdropped, bseg *brs)
3152 {
3153 boolean succeeded;
3154 
3155 succeeded = TRUE;
3156 switch((int)eventtype) {
3157    case 'c' :
3158       coalesce(op,data,tymeslice,alines,numalines,newtyme,nodenumber,
3159          numnodes,rootdropped,brlines);
3160       break;
3161    case 'r' :
3162       succeeded = recomb(op,data,tymeslice,alines,numalines,newtyme,
3163          siteptr,nodenumber,numnodes);
3164       break;
3165    case 'b' :
3166       succeeded = brlistrecomb(op,data,tymeslice,alines,numalines,
3167          brlines,newtyme,siteptr,nodenumber,numnodes,brs);
3168       break;
3169    case '0' :
3170       break;
3171    default :
3172       fprintf(ERRFILE,"ERROR:makeevent impossible case: can't get here\n");
3173       break;
3174 }
3175 
3176 return(succeeded);
3177 } /* makeevent */
3178 
3179 
growlineages(option_struct * op,data_fmt * data,tree * growtree,tree * oldtree,tlist * tstart,brlist ** brlines,linlist ** alines,long * numalines,double offsetstart,boolean ** nodenumber,long * numnodes,long * siteptr)3180 boolean growlineages(option_struct *op, data_fmt *data, tree *growtree,
3181    tree *oldtree, tlist *tstart, brlist **brlines, linlist **alines,
3182    long *numalines, double offsetstart, boolean **nodenumber,
3183    long *numnodes, long *siteptr)
3184 {
3185 tlist *tymeslice;
3186 double btyme, obtyme, newtyme, offset;
3187 boolean succeeded, rootdropped;
3188 char eventtype;
3189 bseg brs;
3190 
3191 tymeslice = tstart;
3192 offset = offsetstart;
3193 rootdropped = FALSE;
3194 succeeded = TRUE;
3195 
3196 while(tymeslice != NULL) {
3197 
3198 /* just drop the root if you're in the last interval but don't make the
3199    root active til you're below the oldtree->root->back */
3200    if (tymeslice->succ == NULL) {
3201       btyme = curtree->root->back->tyme;
3202       obtyme = oldtree->root->back->tyme;
3203       while (obtyme > btyme) {
3204          init_numnewactive(op,data,growtree,brlines,tymeslice->eventnode);
3205          newtyme = tymeslice->eventnode->tyme + offset +
3206             eventprob(op,data,(*alines),tymeslice,brlines,&eventtype,&brs);
3207          if (newtyme <= obtyme) {
3208             succeeded = makeevent(op,data,growtree,tymeslice,brlines,alines,
3209                numalines,newtyme,nodenumber,numnodes,siteptr,eventtype,
3210                rootdropped,&brs);
3211             if (!succeeded) break;
3212             if (succeeded && eventtype != '0') tymeslice = tymeslice->succ;
3213          }
3214          btyme = newtyme;
3215          offset = 0.0;
3216          if ((*numalines) == 0 && !(*brlines)) break;
3217       }
3218       if ((*numalines) == 0 && !(*brlines)) break;
3219       if (!succeeded) break;
3220       succeeded = rootdrop(op,data,tymeslice,obtyme,alines,numalines,
3221          siteptr,nodenumber,numnodes,brlines);
3222       rootdropped = TRUE;
3223       break;
3224    }
3225 
3226    init_numnewactive(op,data,growtree,brlines,tymeslice->eventnode);
3227    newtyme = tymeslice->eventnode->tyme + offset +
3228       eventprob(op,data,(*alines),tymeslice,brlines,&eventtype,&brs);
3229    if (newtyme <= tymeslice->age) {
3230       succeeded = makeevent(op,data,growtree,tymeslice,brlines,alines,
3231          numalines,newtyme,nodenumber,numnodes,siteptr,eventtype,
3232          rootdropped,&brs);
3233       if ((*numalines) == 0 && !(*brlines)) break;
3234    }
3235    if ((*numalines) == 0 && !(*brlines)) break;
3236    if (!succeeded) break;
3237    if (tymeslice->succ) tymeslice = tymeslice->succ;
3238    offset = 0.0;
3239 }
3240 
3241 if (!succeeded) {
3242    numdropped++;
3243    finishbadtree(op,data,growtree,alines,numalines,nodenumber,numnodes,
3244       rootdropped,brlines);
3245 }
3246 
3247 return(succeeded);
3248 
3249 } /* growlineages */
3250 
makedrop(option_struct * op,data_fmt * data)3251 boolean makedrop(option_struct *op, data_fmt *data)
3252 {
3253 long i, numnodes, numalines, nummarkers, *oldsiteptr, *siteptr;
3254 double offset;
3255 linlist *alines;
3256 brlist *brlines;
3257 tlist *tymeslice;
3258 boolean accept_change, *nodenumber;
3259 node *p;
3260 tree *oldtree;
3261 
3262 oldsiteptr = NULL;
3263 siteptr = data->siteptr;
3264 
3265 /* copy the original tree configuration */
3266 oldtree = copytree(op,data,curtree);
3267 numnodes = 2 * oldtree->numcoals + 2;
3268 nodenumber = (boolean *)calloc(1,numnodes*sizeof(boolean));
3269 nummarkers = getdata_nummarkers(op,data);
3270 for(i = 0; i < numnodes; i++) nodenumber[i] = TRUE;
3271 if(op->datatype == 'n' || op->datatype == 's') {
3272    oldsiteptr = (long *)calloc(nummarkers,sizeof(long));
3273    memcpy(oldsiteptr,siteptr,nummarkers*sizeof(long));
3274 }
3275 
3276 /* pick a spot to cut */
3277 alines = NULL;
3278 p = pickbranch(op,data,curtree,&tymeslice,&offset);
3279 if (op->fc) addlinlist(&alines,p,count_activefc(op,data,p));
3280 else addlinlist(&alines,p,count_active(op,data,p));
3281 numalines = 1;
3282 
3283 brlines = NULL;
3284 tag_futile(p->back);
3285 traverse_flagbelow(curtree,p->back);
3286 remove_futile(op,data,curtree,oldtree,p,nodenumber,&brlines);
3287 accept_change = TRUE;
3288 
3289 accept_change = growlineages(op,data,curtree,oldtree,tymeslice,&brlines,
3290    &alines,&numalines,offset,&nodenumber,&numnodes,siteptr);
3291 
3292 if (accept_change) {
3293    renumber_nodes(op,data,curtree);
3294    remove_excess_tree(op,data,curtree,siteptr);
3295    renumber_nodes(op,data,curtree);
3296 #if ALWAYS_ACCEPT
3297    curtree->likelihood = oldtree->likelihood;
3298    accept_change = testratio(op,data,oldtree,curtree,'d');
3299 #endif
3300 #if !ALWAYS_ACCEPT
3301    traverse_flagbelow(curtree,p->back);
3302    if (op->datatype == 'n' || op->datatype == 's')
3303       rebuild_alias(op,data,siteptr);
3304    localeval(op,data,curtree->root->back,FALSE);
3305    curtree->coalprob = coalprob(op,data,curtree,theta0,rec0);
3306    accept_change = testratio(op,data,oldtree,curtree,'d');
3307 #endif
3308 
3309 }
3310 
3311 #if ALWAYS_REJECT
3312    op->numout[1]++;
3313    scoretree(op,data,0L);
3314    accept_change = FALSE;
3315 #endif
3316 
3317 free(nodenumber);
3318 freelinlist(alines);
3319 
3320 if (accept_change) {
3321    freetree(op,data,oldtree);
3322    if (op->datatype == 'n' || op->datatype == 's') free(oldsiteptr);
3323    return(TRUE);
3324 } else {
3325    freetree(op,data,curtree);
3326    curtree = oldtree;
3327    if (op->datatype == 'n' || op->datatype == 's') {
3328       memcpy(siteptr,oldsiteptr,nummarkers*sizeof(long));
3329       free(oldsiteptr);
3330    }
3331    return(FALSE);
3332 }
3333 
3334 } /* makedrop */
3335 
3336 
countrec(tlist * start)3337 long countrec(tlist *start)
3338 {
3339 long accum;
3340 tlist *t;
3341 
3342 accum = 0;
3343 for (t = start; t != NULL; t = t->succ)
3344    if (isrecomb(t->eventnode)) accum++;
3345 
3346 return(accum);
3347 
3348 } /* countrec */
3349 
findrec(tlist * start,long target)3350 node *findrec(tlist *start, long target)
3351 {
3352 long accum;
3353 tlist *t;
3354 
3355 accum = 0;
3356 for (t = start; t != NULL; t = t->succ) {
3357    if (isrecomb(t->eventnode)) accum++;
3358    if (accum == target) return(findunique(t->eventnode));
3359 }
3360 
3361 fprintf(ERRFILE,"ERROR:findrec--unable to find recombination #%ld\n",target);
3362 exit(-1);
3363 
3364 } /* findrec */
3365 
twiddle(option_struct * op,data_fmt * data)3366 boolean twiddle(option_struct *op, data_fmt *data)
3367 {
3368 long i, numrecs, target, *oldsiteptr, numnodes, numalines, *siteptr;
3369 double activelinks;
3370 node *p;
3371 boolean accept_change, *nodenumber;
3372 tlist *tstart;
3373 brlist *brlines;
3374 linlist *alines;
3375 tree *oldtree;
3376 
3377 numrecs = countrec(curtree->tymelist);
3378 if (!numrecs) return(FALSE);
3379 
3380 oldtree = copytree(op,data,curtree);
3381 
3382 target = (long)(randum()*numrecs) + 1;
3383 p = findrec(curtree->tymelist,target);
3384 tstart = gettymenode(curtree,p->number);
3385 
3386 siteptr = data->siteptr;
3387 oldsiteptr = (long *)calloc(getdata_nummarkers(op,data),sizeof(long));
3388 memcpy(oldsiteptr,siteptr,getdata_nummarkers(op,data)*sizeof(long));
3389 
3390 /* now choose the new recombination point, adjusting for the fact that
3391    the active sites don't necessairly start at the beginning of the
3392    sequence */
3393 if (op->fc) {
3394    activelinks = count_activefc(op,data,p);
3395    activelinks = randum()*activelinks;
3396    target = choosepsitefc(op,data,p->back,activelinks);
3397 } else {
3398    activelinks = count_active(op,data,p);
3399    activelinks = randum()*activelinks;
3400    target = choosepsite(op,data,p->back,activelinks);
3401 }
3402 
3403 if (!p->back->ranges[0])
3404     fprintf(ERRFILE,"ERROR:twiddle chose a dead branch!\n");
3405 
3406 /* 50% chance which branch represents the "first" part of the sites */
3407 if (randum() > 0.5) {
3408    p->next->recstart = 0;
3409    p->next->recend = target;
3410    p->next->next->recstart = target + 1;
3411    p->next->next->recend = countsites(op,data) - 1;
3412 } else {
3413    p->next->recstart = target + 1;
3414    p->next->recend = countsites(op,data) - 1;
3415    p->next->next->recstart = 0;
3416    p->next->next->recend = target;
3417 }
3418 
3419 /* fix up the ranges and siteptr info, construct the brlist;
3420    startting drop_brifx_ranges at tstart->prev because a recombination
3421    should never be the eventnode of the first entry of the tymelist */
3422 brlines = NULL;
3423 drop_brfix(op,data,curtree,tstart->prev,&brlines);
3424 if (op->datatype == 'n' || op->datatype == 's')
3425    rebuild_alias(op,data,siteptr);
3426 
3427 /* now reevaluate the tree for added recombinations */
3428 alines = NULL;
3429 numalines = 0;
3430 numnodes = getdata_numtips(op,data) + counttymelist(curtree->tymelist);
3431 nodenumber = (boolean *)calloc(numnodes,sizeof(boolean));
3432 for(i = 0; i < numnodes; i++) nodenumber[i] = TRUE;
3433 
3434 accept_change = growlineages(op,data,curtree,oldtree,tstart,&brlines,
3435    &alines,&numalines,0.0,&nodenumber,&numnodes,siteptr);
3436 
3437 if (accept_change) {
3438    renumber_nodes(op,data,curtree);
3439    remove_excess_tree(op,data,curtree,siteptr);
3440    renumber_nodes(op,data,curtree);
3441 /* root->back's range info may not be set; and must be hand set here. */
3442    if(curtree->root->back->ranges[0] != 1L)
3443       addrange(&curtree->root->back->ranges,0L,countsites(op,data)-1);
3444 #if ALWAYS_ACCEPT
3445    curtree->likelihood = oldtree->likelihood;
3446    accept_change = testratio(op,data,oldtree,curtree,'t');
3447 #endif
3448 #if !ALWAYS_ACCEPT
3449    traverse_flagbelow(curtree,p->back);
3450    if (op->datatype == 'n' || op->datatype == 's')
3451       rebuild_alias(op,data,siteptr);
3452    localeval(op,data,curtree->root->back,FALSE);
3453    curtree->coalprob = coalprob(op,data,curtree,theta0,rec0);
3454    accept_change = testratio(op,data,oldtree,curtree,'t');
3455 #endif
3456 }
3457 
3458 /* if the change was accepted then nothing further needs to be done
3459    except for cleanup */
3460 if (!accept_change) {
3461    freetree(op,data,curtree);
3462    curtree = oldtree;
3463    memcpy(siteptr,oldsiteptr,getdata_nummarkers(op,data)*sizeof(long));
3464 } else freetree(op,data,oldtree);
3465 
3466 free(nodenumber);
3467 free(oldsiteptr);
3468 
3469 return(accept_change);
3470 
3471 } /* twiddle */
3472 
3473 
3474 /******************************************************************
3475  * isprohibited() returns TRUE if the "value" is contained in the *
3476  * passed "badstuff" and FALSE otherwise.                         */
isprohibited(long value,long numbad,long * badstuff)3477 boolean isprohibited(long value, long numbad, long *badstuff)
3478 {
3479 long bad;
3480 
3481 for(bad = 0; bad < numbad; bad++)
3482    if (value == badstuff[bad]) return(TRUE);
3483 
3484 return(FALSE);
3485 
3486 } /* isprohibited */
3487 
3488 
3489 /*******************************************************************
3490  * isinvariant() returns TRUE if the site is invariant for a given *
3491  * creature, otherwise FALSE                                       */
isinvariant(option_struct * op,data_fmt * data,long site,creature * cr)3492 boolean isinvariant(option_struct *op, data_fmt *data, long site,
3493    creature *cr)
3494 {
3495 char **dna;
3496 
3497 switch(op->datatype) {
3498 case 'a':
3499     break;
3500 case 'b':
3501     break;
3502 case 'm':
3503     break;
3504 case 'n':
3505 case 's':
3506    dna = data->dnaptr->seqs[population][locus];
3507    if (dna[cr->haplotypes[0]->number-1][site] ==
3508       dna[cr->haplotypes[1]->number-1][site])
3509       return(TRUE);
3510    break;
3511 }
3512 
3513 return(FALSE);
3514 
3515 } /* isinvariant */
3516 
3517 
3518 /**********************************************
3519  * choose_flipsite() returns a valid flipsite */
choose_flipsite(option_struct * op,data_fmt * data,creature * cr,long numprohibited,long * prohibited)3520 long choose_flipsite(option_struct *op, data_fmt *data, creature *cr,
3521    long numprohibited, long *prohibited)
3522 {
3523 long choice;
3524 
3525 do {
3526    choice = (long)(randum()*cr->numflipsites);
3527 } while (isprohibited(choice,numprohibited,prohibited));
3528 
3529 return(cr->flipsites[choice]);
3530 
3531 } /* choose_flipsite */
3532 
3533 
3534 /********************************************************************
3535  * datachangesite() flips a passed site between two elements of the *
3536  * actual data matrix.                                              */
datachangesite(option_struct * op,data_fmt * data,node * p1,node * p2,long site)3537 void datachangesite(option_struct *op, data_fmt *data, node *p1, node *p2,
3538    long site)
3539 {
3540 char tempbase;
3541 
3542 tempbase = data->dnaptr->seqs[population][locus][p1->number-1][site];
3543 data->dnaptr->seqs[population][locus][p1->number-1][site] =
3544    data->dnaptr->seqs[population][locus][p2->number-1][site];
3545 data->dnaptr->seqs[population][locus][p2->number-1][site] = tempbase;
3546 
3547 } /* datachangesite */
3548 
3549 
3550 /*****************************************************************
3551  * fliphap() flips NUMHAPFLIP sites among the haplotypes of a    *
3552  * randomly chosen creature of the passed in tree.  The sites to *
3553  * be flipped are chosen randomly amongst the eligible sites of  *
3554  * that creature.                                                */
fliphap(option_struct * op,data_fmt * data,tree * tr)3555 boolean fliphap(option_struct *op, data_fmt *data, tree *tr)
3556 {
3557 long i, j, flipsite, numcreatures, numslice, numcategs, datanumsites,
3558    *oldsiteptr, *flippedsites, *siteptr;
3559 double ***temp;
3560 creature *cr;
3561 tree *oldtree;
3562 boolean accept_change;
3563 
3564 datanumsites = getdata_nummarkers(op,data);
3565 siteptr = data->siteptr;
3566 
3567 oldtree = copytree(op,data,tr);
3568 oldsiteptr = (long *)calloc(datanumsites,sizeof(long));
3569 memcpy(oldsiteptr,siteptr,datanumsites*sizeof(long));
3570 
3571 numslice = (op->panel) ? NUMSLICE : 1L;
3572 numcategs = op->categs;
3573 
3574 temp = (double ***)calloc(op->categs,sizeof(double **));
3575 temp[0] = (double **)calloc(op->categs*numslice,sizeof(double *));
3576 for(i = 1; i < op->categs; i++) temp[i] = temp[0] + i*numslice;
3577 temp[0][0] = (double *)calloc(op->categs*numslice*4,sizeof(double));
3578 for(i = 0; i < op->categs; i++)
3579    for(j = 0; j < numslice; j++)
3580       temp[i][j] = temp[0][0] + i*numslice*4 + j*4;
3581 
3582 
3583 flippedsites = (long *)calloc(NUMHAPFLIP,sizeof(long));
3584 
3585 numcreatures = getdata_numtips(op,data)/NUMHAPLOTYPES;
3586 do {
3587    cr = &(tr->creatures[(long)(randum()*numcreatures)]);
3588 } while(cr->numflipsites == 0);
3589 
3590 /* debug DEBUG warning WARNING--this code is two haplotype specific */
3591 /* and it is also dna/snp specific!!!!                              */
3592 for(i = 0; i < NUMHAPFLIP; i++) {
3593    flippedsites[i] = flipsite = choose_flipsite(op,data,cr,i,flippedsites);
3594    /* first flip the x-arrays */
3595    memcpy(temp[0][0],cr->haplotypes[0]->x->s[flipsite][0][0],
3596       numcategs*numslice*4*sizeof(double));
3597    memcpy(cr->haplotypes[0]->x->s[flipsite][0][0],
3598       cr->haplotypes[1]->x->s[flipsite][0][0],
3599       numcategs*numslice*4*sizeof(double));
3600    memcpy(cr->haplotypes[1]->x->s[flipsite][0][0],temp[0][0],
3601       numcategs*numslice*4*sizeof(double));
3602    /* then flip the actual data */
3603    datachangesite(op,data,cr->haplotypes[0],cr->haplotypes[1],flipsite);
3604 }
3605 
3606 /* can just rebuild_alias() because flippable sites can no
3607    longer be aliased */
3608 if (op->datatype == 'n' || op->datatype == 's')
3609    rebuild_alias(op,data,siteptr);
3610 
3611 for(i = 0; i < NUMHAPLOTYPES; i++)
3612    traverse_flagbelow(tr,cr->haplotypes[i]->back);
3613 localeval(op,data,tr->root->back,FALSE);
3614 tr->coalprob = coalprob(op,data,tr,theta0,rec0);
3615 accept_change = testratio(op,data,oldtree,tr,'f');
3616 #if ALWAYS_ACCEPT
3617 tr->likelihood = oldtree->likelihood;
3618 accept_change = testratio(op,data,oldtree,tr,'f');
3619 #endif
3620 
3621 if (!accept_change) {
3622    for(i = 0; i < NUMHAPFLIP; i++)
3623       datachangesite(op,data,cr->haplotypes[1],cr->haplotypes[0],
3624          flippedsites[i]);
3625    freetree(op,data,curtree);
3626    curtree = oldtree;
3627    memcpy(siteptr,oldsiteptr,datanumsites*sizeof(long));
3628 } else freetree(op,data,oldtree);
3629 
3630 free(oldsiteptr);
3631 free(flippedsites);
3632 free(temp[0][0]);
3633 free(temp[0]);
3634 free(temp);
3635 
3636 return(accept_change);
3637 
3638 } /* fliphap */
3639 
3640 
3641 /***********************************************************
3642  * isintymelist() returns TRUE if the nodelet "p" is among *
3643  * the nodelets in the tymelist; FALSE otherwise.          */
isintymelist(option_struct * op,data_fmt * data,tlist * start,node * p)3644 boolean isintymelist(option_struct *op, data_fmt *data,
3645    tlist *start, node *p)
3646 {
3647 tlist *t;
3648 
3649 for(t = start; t != NULL; t = t->succ) {
3650    if (p == t->eventnode) return(TRUE);
3651    if (p->next) {
3652       if (p->next == t->eventnode) return(TRUE);
3653       if (p->next->next)
3654          if (p->next->next == t->eventnode) return(TRUE);
3655    }
3656 }
3657 
3658 return(FALSE);
3659 
3660 } /* isintymelist */
3661 
3662 
3663 /**************************************************************
3664  * flipdrop_prunebr() removes from the brlist the bad entries *
3665  * created by serial-calling remove_futile().                 */
flipdrop_prunebr(option_struct * op,data_fmt * data,tree * tr,brlist ** brlines)3666 void flipdrop_prunebr(option_struct *op, data_fmt *data, tree *tr,
3667    brlist **brlines)
3668 {
3669 brlist *br, *brsucc;
3670 
3671 for(br = (*brlines); br != NULL; br = brsucc) {
3672    brsucc = br->succ;
3673    if (isintymelist(op,data,tr->tymelist,br->branchtop)) continue;
3674    br_remove(brlines,br);
3675 }
3676 
3677 } /* flipdrop_prunebr */
3678 
3679 
3680 /*****************************************************************
3681  * flipdrop() flips NUMHAPFLIP sites among the haplotypes of a   *
3682  * randomly chosen creature of the passed in tree, and then      *
3683  * does a drop on one or both affected tips.  The sites to       *
3684  * be flipped are chosen randomly amongst the eligible sites of  *
3685  * that creature.                                                */
3686 
3687 /* WARNING:  the logic for dropping multiple lines here works    *
3688  * only for two tips, not in the general case!                   */
3689 
flipdrop(option_struct * op,data_fmt * data,tree * tr,long numdrop)3690 boolean flipdrop(option_struct *op, data_fmt *data, tree *tr,
3691    long numdrop)
3692 {
3693 long i, j, flipsite, numcreatures, numslice, numcategs, datanumsites,
3694    *oldsiteptr, *flippedsites, *siteptr;
3695 double ***temp;
3696 creature *cr;
3697 tree *oldtree;
3698 linlist *alines;
3699 brlist *brlines;
3700 boolean accept_change, *nodenumber;
3701 node *p;
3702 long numnodes, numalines;
3703 
3704 datanumsites = getdata_nummarkers(op,data);
3705 siteptr = data->siteptr;
3706 
3707 oldtree = copytree(op,data,tr);
3708 oldsiteptr = (long *)calloc(datanumsites,sizeof(long));
3709 memcpy(oldsiteptr,siteptr,datanumsites*sizeof(long));
3710 numnodes = 2 * oldtree->numcoals + 2;
3711 nodenumber = (boolean *)calloc(1,numnodes*sizeof(boolean));
3712 for(i = 0; i < numnodes; i++) nodenumber[i] = TRUE;
3713 
3714 numslice = (op->panel) ? NUMSLICE : 1L;
3715 numcategs = op->categs;
3716 
3717 temp = (double ***)calloc(op->categs,sizeof(double **));
3718 temp[0] = (double **)calloc(op->categs*numslice,sizeof(double *));
3719 for(i = 1; i < op->categs; i++) temp[i] = temp[0] + i*numslice;
3720 temp[0][0] = (double *)calloc(op->categs*numslice*4,sizeof(double));
3721 for(i = 0; i < op->categs; i++)
3722    for(j = 0; j < numslice; j++)
3723       temp[i][j] = temp[0][0] + i*numslice*4 + j*4;
3724 
3725 
3726 flippedsites = (long *)calloc(NUMHAPFLIP,sizeof(long));
3727 
3728 numcreatures = getdata_numtips(op,data)/NUMHAPLOTYPES;
3729 do {
3730    cr = &(tr->creatures[(long)(randum()*numcreatures)]);
3731 } while(cr->numflipsites == 0);
3732 
3733 /* debug DEBUG warning WARNING--this code is two haplotype specific */
3734 /* and it is also dna/snp specific!!!!                              */
3735 for(i = 0; i < NUMHAPFLIP; i++) {
3736    flippedsites[i] = flipsite = choose_flipsite(op,data,cr,i,flippedsites);
3737    /* first flip the x-arrays */
3738    memcpy(temp[0][0],cr->haplotypes[0]->x->s[flipsite][0][0],
3739       numcategs*numslice*4*sizeof(double));
3740    memcpy(cr->haplotypes[0]->x->s[flipsite][0][0],
3741       cr->haplotypes[1]->x->s[flipsite][0][0],
3742       numcategs*numslice*4*sizeof(double));
3743    memcpy(cr->haplotypes[1]->x->s[flipsite][0][0],temp[0][0],
3744       numcategs*numslice*4*sizeof(double));
3745    /* then flip the actual data */
3746    datachangesite(op,data,cr->haplotypes[0],cr->haplotypes[1],flipsite);
3747 }
3748 
3749 /* now cut off the two tips */
3750 alines = NULL;
3751 brlines = NULL;
3752 numalines = 0;
3753 if (numdrop == 1) { /* drop one lineage at random */
3754   if (randum()>= 0.5) i=0;
3755   else i=1;
3756   p = cr->haplotypes[i];
3757   if (op->fc) addlinlist(&alines,p,count_activefc(op,data,p));
3758   else addlinlist(&alines,p,count_active(op,data,p));
3759   numalines++;
3760   tag_futile(p->back);
3761   traverse_flagbelow(curtree,p->back);
3762   remove_futile(op,data,curtree,oldtree,p,nodenumber,&brlines);
3763 } else { /* drop both lineages */
3764   for (i = 0; i < NUMHAPLOTYPES ; i++) {
3765     if (randum()>= 0.5) i=0;
3766     else i=1;
3767     p = cr->haplotypes[i];
3768     if (op->fc) addlinlist(&alines,p,count_activefc(op,data,p));
3769     else addlinlist(&alines,p,count_active(op,data,p));
3770     numalines++;
3771     tag_futile(p->back);
3772     traverse_flagbelow(curtree,p->back);
3773     remove_futile(op,data,curtree,oldtree,p,nodenumber,&brlines);
3774   }
3775   flipdrop_prunebr(op,data,curtree,&brlines);
3776 }
3777 
3778 accept_change = growlineages(op,data,curtree,oldtree,
3779   curtree->tymelist,&brlines,&alines,&numalines,0L,&nodenumber,
3780   &numnodes,siteptr);
3781 if (accept_change) {
3782    renumber_nodes(op,data,curtree);
3783    remove_excess_tree(op,data,curtree,siteptr);
3784    renumber_nodes(op,data,curtree);
3785    rebuild_alias(op,data,siteptr);
3786    for(i = 0; i < NUMHAPLOTYPES; i++)
3787       traverse_flagbelow(curtree,cr->haplotypes[i]);
3788 #if !ALWAYS_ACCEPT
3789    localeval(op,data,tr->root->back,FALSE);
3790    tr->coalprob = coalprob(op,data,tr,theta0,rec0);
3791 #endif
3792 #if ALWAYS_ACCEPT
3793    tr->likelihood = oldtree->likelihood;
3794 #endif
3795    accept_change = testratio(op,data,oldtree,tr,'f');
3796 }
3797 
3798 free(nodenumber);
3799 freelinlist(alines);
3800 
3801 if (!accept_change) {
3802    for(i = 0; i < NUMHAPFLIP; i++)
3803       datachangesite(op,data,cr->haplotypes[1],cr->haplotypes[0],
3804          flippedsites[i]);
3805    freetree(op,data,curtree);
3806    curtree = oldtree;
3807    memcpy(siteptr,oldsiteptr,datanumsites*sizeof(long));
3808 } else freetree(op,data,oldtree);
3809 
3810 free(oldsiteptr);
3811 free(flippedsites);
3812 free(temp[0][0]);
3813 free(temp[0]);
3814 free(temp);
3815 
3816 return(accept_change);
3817 
3818 } /* flipdrop */
3819 
3820 
3821 /*******************************************************************
3822  * addfractrecomb() adds the constant FRACTRECOMB to the number of *
3823  * recombinations scored for the last tree.                        *
3824  * This function should only be called at the end of a chain, and  *
3825  * then only if the trees scored during that chain have no         *
3826  * recombinations in any of them!                                  */
addfractrecomb(option_struct * op,data_fmt * data,long chain,treerec *** treesum)3827 void addfractrecomb(option_struct *op, data_fmt *data, long chain,
3828    treerec ***treesum)
3829 {
3830 long refchain, chaintype;
3831 treerec *lasttree;
3832 
3833 refchain = REF_CHAIN(chain);
3834 chaintype = TYPE_CHAIN(chain);
3835 
3836 lasttree = &treesum[locus][refchain][op->numout[chaintype]-1];
3837 
3838 lasttree->numrecombs += FRACTRECOMB;
3839 
3840 } /* addfractrecomb */
3841 
3842 
3843 /***********************************************************************
3844 * add_one_recomb() runs a special rearrangement that always begins    *
3845 * with a recombination event.  The resulting tree is always accepted, *
3846 * and then is forcibly sampled (replacing the last tree of the chain).*/
add_one_recomb(option_struct * op,data_fmt * data,tree * tr,long * siteptr,long chain)3847 void add_one_recomb(option_struct *op, data_fmt *data, tree *tr,
3848    long *siteptr, long chain)
3849 {
3850 long i, numalines, numnodes, *oldsiteptr, chaintype;
3851 double offset, newtyme, pc, pr;
3852 linlist *alines;
3853 brlist *brlines;
3854 tlist *tymeslice;
3855 node *cutpt;
3856 boolean *nodenumber, succeeded;
3857 tree *oldtree;
3858 
3859 oldtree = copytree(op,data,curtree);
3860 numnodes = 2 * curtree->numcoals + 2;
3861 nodenumber = (boolean *)calloc(numnodes,sizeof(boolean));
3862 for(i = 0; i < numnodes; i++) nodenumber[i] = TRUE;
3863 if(op->datatype == 'n' || op->datatype == 's') {
3864    oldsiteptr = (long *)calloc(getdata_nummarkers(op,data),sizeof(long));
3865    memcpy(oldsiteptr,siteptr,getdata_nummarkers(op,data)*sizeof(long));
3866 }
3867 alines = NULL;
3868 brlines = NULL;
3869 
3870 cutpt = tr->nodep[1];
3871 tymeslice = tr->tymelist;
3872 offset = 0.0;
3873 
3874 if (op->fc) addlinlist(&alines,cutpt,count_activefc(op,data,cutpt));
3875 else addlinlist(&alines,cutpt,count_active(op,data,cutpt));
3876 numalines = 1;
3877 
3878 tag_futile(cutpt->back);
3879 traverse_flagbelow(curtree,cutpt->back);
3880 remove_futile(op,data,curtree,oldtree,cutpt,nodenumber,&brlines);
3881 
3882 /* startoff with 1 recombination */
3883 /* generate the time the recombination will occur at */
3884 pc = 2.0 * countinactive(op,tymeslice,alines)/theta0;
3885 pr = rec0 * alines->activesites;
3886 newtyme = tymeslice->eventnode->tyme + offset -
3887    log(randum())/(pc + pr);
3888 
3889 /* find the tymeslice that corresponds with that time */
3890 for(; tymeslice->age < newtyme; tymeslice = tymeslice->succ)
3891    ;
3892 
3893 /* put in the recombination */
3894 succeeded = recomb(op,data,tymeslice,&alines,&numalines,newtyme,
3895    siteptr,&nodenumber,&numnodes);
3896 tymeslice = tymeslice->succ;
3897 
3898 succeeded = growlineages(op,data,curtree,oldtree,tymeslice,&brlines,
3899    &alines,&numalines,offset,&nodenumber,&numnodes,siteptr);
3900 
3901 
3902 free(nodenumber);
3903 freelinlist(alines);
3904 
3905 if (succeeded) {
3906    renumber_nodes(op,data,curtree);
3907    remove_excess_tree(op,data,curtree,siteptr);
3908    renumber_nodes(op,data,curtree);
3909    traverse_flagbelow(curtree,cutpt->back);
3910    if (op->datatype == 'n' || op->datatype == 's')
3911       rebuild_alias(op,data,siteptr);
3912    localeval(op,data,curtree->root->back,FALSE);
3913    curtree->coalprob = coalprob(op,data,curtree,theta0,rec0);
3914 
3915    /* now actually sample the generated tree */
3916    chaintype = TYPE_CHAIN(chain);
3917    op->numout[chaintype]--;
3918 
3919    scoretree(op,data,chain);
3920    op->numout[chaintype]++;
3921 }
3922 
3923 freetree(op,data,curtree);
3924 curtree = oldtree;
3925 if (op->datatype == 'n' || op->datatype == 's') {
3926    memcpy(siteptr,oldsiteptr,getdata_nummarkers(op,data)*sizeof(long));
3927    free(oldsiteptr);
3928 }
3929 
3930 
3931 } /* add_one_recomb */
3932