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