/*-----------------* * Function getsam | *-----------------* | Generates a gene genealogy for a locus. */ int gensam(struct params *pparam, char **list, int **pnbvariant, int *pS) { int nsegs=0, k=0, seg=0, ns=0, start=0, end=0, len=0, segsit=0, nsites=0, nsam=0; /* The function returns ns, the number of sgregating sites. * nsegs is the gametes were broken into in tracing back the history of the gametes. * The histories of these segments are passed back to the calling function in the array of structures seglst[] */ struct segl *seglst=NULL; double nsinv=0.0, tseg=0.0, tt=0.0, theta=0.0; void make_gametes(int, struct node*, double, int, int, char**, int, int*, int**, int*, int*); void inititable(int, int, int*); void initimatrix(int, int, int, int**); void biggerimatrix(int, int**); void biggerlist(int, char**); void locate(int, double, double, double*); //// From make_gametes //// void prtree(struct node*, int); double ttime(struct node*, int); int poisso(double); //// From streec.c //// struct segl*segtre_mig(struct c_params*, int*); nsites=pparam->cp.nsites; // Locus lenght available for recombination nsinv=1./nsites; seglst=segtre_mig(&(pparam->cp), &nsegs); // Generate Xove and ARGr, record # segments nsam=pparam->cp.nsam; // # chromo in the sample theta=pparam->mp.theta; // mutation rate given by user ns=0; // # seg sites if(pparam->mp.treeflag) // Case output tree. { theta=pparam->mp.theta; ns=0; for(seg=0, k=0;k<nsegs;seg=seglst[seg].next, k++) { if((pparam->cp.r>0.0)||(pparam->cp.f>0.0)) { end=(k<nsegs-1 ? seglst[seglst[seg].next].beg-1:nsites-1); start=seglst[seg].beg; len=end-start+1; fprintf(stdout, "[%d]", len); } prtree(seglst[seg].ptree, nsam); if((theta==0.0)) free(seglst[seg].ptree); } } //--- Loop along all segments ---// for(seg=0, k=0;k<nsegs; seg=seglst[seg].next, k++) { end=(k<nsegs-1 ? seglst[seglst[seg].next].beg-1:nsites-1); // End of segment start=seglst[seg].beg; // beginning of segment len=end-start+1; // Lengh of segment tseg=len*(theta/nsites); // Mutation rate along the segment tt=ttime(seglst[seg].ptree, nsam); // Total time in the tree for this segment segsit=poisso(tseg*tt); // get # segsites along genealogy for the segment //--- Realloc memory if # segsite bigger than max previously define ---// if((segsit+ns)>=maxsites) { maxsites=segsit+ns+SITESINC; // Bigger Max sites biggerlist(nsam, list); // Increase list of haplotype typeseg=(int*)realloc(typeseg, maxsites*sizeof(int)); // Increase # seg sites in typeseg biggerimatrix(pparam->cp.npop+1, pnbvariant); // Increase matrix of variant } //--- Initialize table of variant and segType ---// initimatrix(ns, ns+segsit, pparam->cp.npop+1, pnbvariant); inititable(ns, segsit+ns, typeseg); make_gametes(nsam, seglst[seg].ptree, tt, segsit, ns, list, pparam->cp.npop, pparam->cp.config, pnbvariant, typeseg, pS); // Make gametes (Put segsites on gene genealogy) free(seglst[seg].ptree); // Free memory ns+=segsit; // Total # seg sites } for(k=0;k<nsam;k++) list[k][ns]='\0'; // End of haplotype strings return(ns); // Total # segsites }// End Gensam
int gensam( char **list, double *pprobss, double *ptmrca, double *pttot ) { int nsegs, h, i, k, j, seg, ns, start, end, len, segsit ; struct segl *seglst, *segtre_mig(struct c_params *p, int *nsegs ) ; /* used to be: [MAXSEG]; */ double nsinv, tseg, tt, ttime(struct node *, int nsam), ttimemf(struct node *, int nsam, int mfreq) ; double *pk; int *ss; int segsitesin,nsites; double theta, es ; int nsam, mfreq ; void prtree( struct node *ptree, int nsam); void make_gametes(int nsam, int mfreq, struct node *ptree, double tt, int newsites, int ns, char **list ); void ndes_setup( struct node *, int nsam ); nsites = pars.cp.nsites ; nsinv = 1./nsites; seglst = segtre_mig(&(pars.cp), &nsegs ) ; nsam = pars.cp.nsam; segsitesin = pars.mp.segsitesin ; theta = pars.mp.theta ; mfreq = pars.mp.mfreq ; if( pars.mp.treeflag ) { ns = 0 ; for( seg=0, k=0; k<nsegs; seg=seglst[seg].next, k++) { if( (pars.cp.r > 0.0 ) || (pars.cp.f > 0.0) ) { end = ( k<nsegs-1 ? seglst[seglst[seg].next].beg -1 : nsites-1 ); start = seglst[seg].beg ; len = end - start + 1 ; fprintf(stdout,"[%d]", len); } prtree( seglst[seg].ptree, nsam ) ; if( (segsitesin == 0) && ( theta == 0.0 ) && ( pars.mp.timeflag == 0 ) ) free(seglst[seg].ptree) ; } } if( pars.mp.timeflag ) { tt = 0.0 ; for( seg=0, k=0; k<nsegs; seg=seglst[seg].next, k++) { if( mfreq > 1 ) ndes_setup( seglst[seg].ptree, nsam ); end = ( k<nsegs-1 ? seglst[seglst[seg].next].beg -1 : nsites-1 ); start = seglst[seg].beg ; if( (nsegs==1) || ( ( start <= nsites/2) && ( end >= nsites/2 ) ) ) *ptmrca = (seglst[seg].ptree + 2*nsam-2) -> time ; len = end - start + 1 ; tseg = len/(double)nsites ; if( mfreq == 1 ) tt += ttime(seglst[seg].ptree,nsam)*tseg ; else tt += ttimemf(seglst[seg].ptree,nsam, mfreq)*tseg ; if( (segsitesin == 0) && ( theta == 0.0 ) ) free(seglst[seg].ptree) ; } *pttot = tt ; } if( (segsitesin == 0) && ( theta > 0.0) ) { ns = 0 ; for( seg=0, k=0; k<nsegs; seg=seglst[seg].next, k++) { if( mfreq > 1 ) ndes_setup( seglst[seg].ptree, nsam ); end = ( k<nsegs-1 ? seglst[seglst[seg].next].beg -1 : nsites-1 ); start = seglst[seg].beg ; len = end - start + 1 ; tseg = len*(theta/nsites) ; if( mfreq == 1) tt = ttime(seglst[seg].ptree, nsam); else tt = ttimemf(seglst[seg].ptree, nsam, mfreq ); segsit = poisso( tseg*tt ); if( (segsit + ns) >= maxsites ) { maxsites = segsit + ns + SITESINC ; posit = (double *)realloc(posit, maxsites*sizeof(double) ) ; biggerlist(nsam, list) ; } make_gametes(nsam,mfreq,seglst[seg].ptree,tt, segsit, ns, list ); free(seglst[seg].ptree) ; locate(segsit,start*nsinv, len*nsinv,posit+ns); ns += segsit; } } else if( segsitesin > 0 ) { pk = (double *)malloc((unsigned)(nsegs*sizeof(double))); ss = (int *)malloc((unsigned)(nsegs*sizeof(int))); if( (pk==NULL) || (ss==NULL) ) perror("malloc error. gensam.2"); tt = 0.0 ; for( seg=0, k=0; k<nsegs; seg=seglst[seg].next, k++) { if( mfreq > 1 ) ndes_setup( seglst[seg].ptree, nsam ); end = ( k<nsegs-1 ? seglst[seglst[seg].next].beg -1 : nsites-1 ); start = seglst[seg].beg ; len = end - start + 1 ; tseg = len/(double)nsites ; if( mfreq == 1 ) pk[k] = ttime(seglst[seg].ptree,nsam)*tseg ; else pk[k] = ttimemf(seglst[seg].ptree,nsam, mfreq)*tseg ; tt += pk[k] ; } if( theta > 0.0 ) { es = theta * tt ; *pprobss = exp( -es )*pow( es, (double) segsitesin) / segfac ; } if( tt > 0.0 ) { for (k=0; k<nsegs; k++) pk[k] /= tt ; mnmial(segsitesin,nsegs,pk,ss); } else for( k=0; k<nsegs; k++) ss[k] = 0 ; ns = 0 ; for( seg=0, k=0; k<nsegs; seg=seglst[seg].next, k++) { end = ( k<nsegs-1 ? seglst[seglst[seg].next].beg -1 : nsites-1 ); start = seglst[seg].beg ; len = end - start + 1 ; tseg = len/(double)nsites; make_gametes(nsam,mfreq,seglst[seg].ptree,tt*pk[k]/tseg, ss[k], ns, list); free(seglst[seg].ptree) ; locate(ss[k],start*nsinv, len*nsinv,posit+ns); ns += ss[k] ; } free(pk); free(ss); } for(i=0; i<nsam; i++) list[i][ns] = '\0' ; return( ns ) ; }